ColdFusion 10 - An Augmented Virtual File System (VFS)

Posted March 5, 2012 at 10:08 AM by Ben Nadel

Tags: ColdFusion

Last week, I explored ColdFusion 10's new ability to load custom Java Classes and JAR files on a per-application basis. In that exploration, I ended up creating a number of Java classes and a ColdFusion component (CFC) that needed to work together. This got me thinking about code deployment - if I created a Java class that depended on a ColdFusion component, could I deploy them together in the same JAR file? With ColdFusion 10's enhanced virtual file system (VFS), the answer is surprisingly, Yes. In fact, a ColdFusion component can now be loaded directly from a JAR file.

NOTE: At the time of this writing, ColdFusion 10 was in public beta.

To recap what I did last week, I came up with a way to enable Java to invoke ColdFusion closures and ColdFusion component methods. I did this by storing a dynamic Java proxy to the ColdFusionProxy.cfc component as a static Java class property. This, obviously, created a strong coupling between the Java class files to the ColdFusionProxy.cfc component. As such, I wanted to deploy them together in a single JAR file.

The result of this thinking was the cf10.jar file which created an archive with the following, embedded files:

  • cf10.jar !/ com / bennadel / cf10 / Core.class
  • cf10.jar !/ com / bennadel / cf10 / CFArray.class
  • cf10.jar !/ com / bennadel / cf10 / ColdFusionProxy.cfc

As you can see, this JAR file contains two Java classes and my ColdFusion component.

The augmented virtual file system in ColdFusion 10 provides us with read-access to JAR files. So, in order to create a dynamic Java proxy for this archived ColdFusion component, I simply had to map the JAR file path to a custom ColdFusion mapping:

Application.cfc - Our ColdFusion Application Framework Component

  • <cfscript>
  • // NOTE: CFScript tags add purely for Gist color-coding. Remove.
  •  
  • component
  • output="false"
  • hint="I define the application settings and event handlers."
  • {
  •  
  •  
  • // Define our standard Application settings.
  • this.name = hash( getCurrentTemplatePath() );
  • this.applicationTimeout = createTimeSpan( 0, 0, 0, 5 );
  •  
  • // Map aspects of the Virtial File System (VFS). Notice that the
  • // mapped file here ends with "!". This separates the JAR file
  • // path from the embedded, archived files.
  • this.mappings[ "/cf10jar" ] = (
  • "jar://" &
  • getDirectoryFromPath( getCurrentTemplatePath() ) &
  • "lib/cf10.jar!"
  • );
  •  
  • // Define our per-application Java library settings. Here, we
  • // are telling it to load our CF10.jar file.
  • this.javaSettings = {
  • loadPaths: [
  • "./lib/cf10.jar"
  • ],
  • loadColdFusionClassPath: true
  • };
  •  
  •  
  • // I initialize the application.
  • function onApplicationStart(){
  •  
  • // Create a dynamic proxy using a ColdFusion Component that
  • // is loacated in our CF10 JAR file. Since we mapped the
  • // location of the JAR file itself, now all we need to
  • // supply is the dot-file-path to the embedded component.
  • var coldfusionProxy = createDynamicProxy(
  • "/cf10jar.com.bennadel.cf10.ColdFusionProxy",
  • [ "com.bennadel.cf10.ColdFusionProxy" ]
  • );
  •  
  • // Now that we have our proxy, let's initialize our custom
  • // JAVA library with our ColdFusion invocation "tunnel."
  • // This will enable our Java classes to be able to invoke
  • // ColdFusion closures and component methods.
  • createObject( "java", "com.bennadel.cf10.Core" )
  • .setColdFusionProxy( coldfusionProxy )
  • ;
  •  
  • // Return true so the application can load.
  • return( true );
  • }
  •  
  •  
  • }
  •  
  • // NOTE: CFScript tags add purely for Gist color-coding. Remove.
  • </cfscript>

As you can see, I am creating a ColdFusion application mapping of the virtual file path:

jar://[app directory]/lib/cf10.jar!

... to the mapping:

/cf10jar

Notice that the virtual file path contains a trailing "!". This character separates the physical file path (JAR) from the embedded file paths (archived files). Everything after the "!" will be considered an in-JAR file path.

Once this mapping has been set up, I can then create a ColdFusion component using the fully qualified component path:

/cf10jar.com.bennadel.cf10.ColdFusionProxy

As you can see, this component class path starts off with "/cf10jar", our custom ColdFusion mapping. But then, we use the standard dot-notation to define the in-JAR file path to the ColdFusionProxy.cfc component. We're using the virtual file system to load a ColdFusion component out of a JAR file archive.

The ColdFusion 10 virtual file system (VFS) is pretty darn cool. It provides file-based access to the following protocols:

  • BZIP2
  • File
  • FTP
  • FTPS
  • GZIP
  • HTTP
  • HTTPS
  • JAR
  • RAM
  • RES
  • SFTP
  • TAR
  • TEMP
  • WebDAV
  • ZIP

Not all of these protocols provide read, write, and list access. Many provide only read-access to virtual files. The list of functionality and limitations can be seen on the Apache Commons website.

NOTE: ColdFusion 9.01 and ColdFusion 10 also support Amazon's Simple Storage Service (S3) through the protocol, "s3://". This integration is much more robust and requires application settings to be defined in the Application.cfc ColdFusion framework component.

Wile not all protocols in the ColdFusion virtual file system (VFS) support both read and write access, I think the unified access notation is going to be a very useful feature.


You Might Also Be Interested In:



Reader Comments

May 31, 2012 at 11:46 PM // reply »
2 Comments

What's the performance like?

Does it run in a ram-disk, or unpack the jar to a temp directory and run it from there?

I presume it doesn't decompress on the fly, cause that would be massively cpu intensive.


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 21, 2013 at 11:51 AM
Ask Ben: Parsing Very Large XML Documents In ColdFusion
Looking at my first ever XML document that I have to parse and put into MS SQL 2000 with CF8. I get it to list the desired Field name, many times over, and have a long list of this field name displa ... read »
May 21, 2013 at 9:25 AM
Turning Off and On Identity Column in SQL Server
you are awesome..i am lucky to get this blog between such a garbage one....Thanks, Prashant ... read »
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
May 20, 2013 at 4:29 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, That's if you're trying to reference a specific row. In this case, we're trying to reference the entire query column as one cohesive value. So, you are correct that if you wanted to output a ... read »
May 20, 2013 at 4:24 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I thought when you used array notation to reference queries you always had to have the row or it would throw a similar error as well? ... read »
May 20, 2013 at 11:45 AM
Using jQuery's Animate() Step Callback Function To Create Custom Animations
This is really useful. I found out that you don't actually have to use a dummy css property (surprisingly). To animate a property in a linear-gradient for instance I did this this.css('someLinearGra ... read »
May 20, 2013 at 10:51 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Josh, Oh snap! You're totally right! I'm not sure I've ever tried that. I did know that you can call a number of other array-methods on ColdFusion query columns: http://www.bennadel.com/blog/167 ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools