How ColdFusion CreateObject() Really Works With Java Objects

Posted May 30, 2007 at 10:06 AM by Ben Nadel

Tags: ColdFusion

I use ColdFusion's CreateObject() method at least a dozen times each day to create wonderful Java objects like String Buffers and File Input Stream. Until recently, I have never really thought about how it actually works - I have just accepted that the black magic under the hood did the job properly. But then, just the other day, I discovered that you could instantiate multiple Java instances off of the same Java class returned by CreateObject():

  • <!--- Get the string buffer class object. --->
  • <cfset objStringBuffer = CreateObject(
  • "java",
  • "java.lang.StringBuffer"
  • ) />
  •  
  • <!---
  • From the string buffer class object, instantiate
  • two sepparate instances of the Java string buffer.
  • --->
  • <cfset objDataOne = objStringBuffer.Init() />
  • <cfset objDataTwo = objStringBuffer.Init() />

When I saw this, I realized that I had no idea how ColdFusion's CreateObject() functionality really worked. After some posting and some back and forth comments, Sammy Larbi, Rupesh Kumar, and Sean Corfield have really helped to clear things up:


 
 
 

 
ColdFusion CreateObject() Functionality For Java  
 
 
 

Apparently, when you call ColdFusion's CreateObject() method to create a Java object, ColdFusion is returning a proxy object to that Java object, not the Java object itself. This proxy object allows you to reference static properties and invoke static methods of that Java class without actually having to instantiate the full Java class. This is good for memory usage and for performance (object instantiation is a costly process).

If you call Init() on that proxy object, it then instantiates the Java object with the given arguments and returns a proxy object wrapped around this new instance (I suspect from the Init() example above that it must create a new proxy object otherwise you probably wouldn't be able to call Init() twice on the same ColdFusion proxy). Similarly, if you attempt to call a non-static method of the Java class, the proxy object will, behind the scenes, call Init() on the Java class (passing no arguments), and use that as the target class going forward.

Of course, this is what I think I understand. This may contain errors and if I get feedback on this, I will update the graphic as necessary. Thanks to all who helped me get this far.




Reader Comments

May 30, 2007 at 10:43 AM // reply »
79 Comments

Thathow I understood it to be after Rupesh's and Sean's comments.


May 30, 2007 at 10:46 AM // reply »
11,238 Comments

Awesome. Thanks for your help and feedback.


Nov 20, 2007 at 12:42 PM // reply »
1 Comments

You can search "Cold" word in http://searchcode.tm-sol.com/. might give you some examples also.

found good examples as well.


Feb 10, 2010 at 12:53 PM // reply »
1 Comments

How do you free the memory used by this object on the coldfusion server?


Feb 10, 2010 at 10:06 PM // reply »
11,238 Comments

@Dan,

You don't have to - the garbage collection will handle that for you.


Mar 9, 2010 at 10:16 AM // reply »
8 Comments

you can also create WebService objects this way.

i.e.:
<cfscript>
dynamicsWS = CreateObject("webservice", "http://192.168.0.100/DynamicsGPWebServices/DynamicsGPService.asmx?WSDL");
</cfscript>

<cfinvoke webservice="#dynamicsWS#" method="GetCompanyList" refreshWSDL="yes" timeout="30" returnvariable="result">
</cfinvoke>

This creates WebService object in your ColdFusion instance (available from administration panel -> webservices) and this object "lives" in there for about 10 (gets deleted if not used).

So I never took CreateObject() for granted :)


Mar 19, 2010 at 9:22 AM // reply »
11,238 Comments

@Dmitry,

Word up - createObject() can do a whole bunch of things. It's probably one of the best updates to the language.


Feb 23, 2011 at 1:51 PM // reply »
8 Comments

Ben, sheds some light on the subject for me. I've recently ventured into a shared hosting enviroment to do some outside work, and quickly ran into the java object disabled issue.

I'm not much of a programer, more a manager and integrator and struggling to find a workaround for some open source I'm using.

Thanks for the overview.


Feb 23, 2011 at 1:54 PM // reply »
11,238 Comments

@Scott,

Glad you liked it. I'm sorry to hear that your Java objects have been disabled on the host. That can definitely get annoying :(


Nov 1, 2011 at 6:07 PM // reply »
1 Comments

One quick point: I'm less certain that "object instantiation is a costly process" - object instantiation is strongly optimized on the JVM, and even reflection has far less cost than before.

IMO, the reason for the init pattern is to allow access to statics with less hoops; though this creates a somewhat schizophrenic API.

Nitpicks aside, thanks for another clear and lucid explanation of one of the details of the CF platform. Your blog has been extremely helpful to me as I learn!


Jan 3, 2012 at 2:49 PM // reply »
1 Comments

I know this is a bit of an old thread, but I recently discovered something relevant. The init() function call on CF proxy objects is not thread safe.

Recently we began having random documents inserted into the incorrect collection on our MongoDB. We tracked it down to our own Mongo driver which leverages the Mongo Java driver as a singleton. However, in concurrency situations, creating new instances of our java class using the above method caused us sometimes to get the wrong instance back.

For example:
Process A calls init("collection1")
Process B calls init("collection2")
Both calls return CF proxy objects with the same instance of our CFMongo class pointing to collection2.

So if you are going to cache your static class in a shared location, like the application scope, you need to only call init() with an exclusion lock. In our case we chose to use CreateObject() each time passing the mongo driver singleton into the constructor.


Mar 7, 2012 at 12:14 PM // reply »
2 Comments

Hi Ben, interesting post.

It looks like I'm running into the CF proxy object as an issue on a routine I'm writing.

I'm importing the Amazon Web Services SDK for Java into a CFC and to initialise the S3 Client you first have to create an authentication object. However passing this object (which is created correctly) to the init() function throws an "An exception occurred while instantiating a Java object. The class must not be an interface or an abstract class" error.

I'm guessing that because this isn't a true Java object the second class doesn't like it?

Anyway here's the code:

  • awsCred = createobject('java',
  • 'com.amazonaws.auth.BasicAWSCredentials').init(
  • accessKey,
  • secretKey
  • );
  • // this works fine; CFDUMP shows correctly instantiated object
  •  
  • s3 = CreateObject( 'java',
  • 'com.amazonaws.services.s3.AmazonS3Client'
  • ).init(awsCred);
  • // this line throws the error

Any ideas how to instantiate a real Java object?

Thanks
James


Mar 8, 2012 at 5:10 AM // reply »
2 Comments

Ignore my earlier post, it appears that the Amazon SDK requires some more third party Jar files in the class path than it comes with, namely httpclient-4.1.1.jar if you're having similar problems.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools