Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at BFusion / BFLEX 2009 (Bloomington, Indiana) with: Peter Farrell and Matt Woodward and Kurt Wiersma
Ben Nadel at BFusion / BFLEX 2009 (Bloomington, Indiana) with: Peter Farrell , Matt Woodward@mpwoodward ) , and Kurt Wiersma

The ColdFusion 10 invoke() Function Works With Most Java Objects

By Ben Nadel on
Tags: ColdFusion

The other day, when I was working on my light-weight ColdFusion wrapper for the OWASP (Open Web Application Security Project) Java Encoder project, I had to dynamically invoke methods on the underlying Java object. In the past, I've had to use the evaluate() function to dynamically invoke Java methods. But, as of ColdFusion 10, the new invoke() function has support for most Java objects.

I say "most" Java objects because invoke() won't actually work on "java.lang.String" instances. If you pass a Java String to the invoke() function, ColdFusion thinks that you are providing the name of a ColdFusion component that you want to instantiate. So, for example, if you try to execute:

  • <cfscript>
  •  
  • input = javaCast( "string", "Good morning Tricia." );
  •  
  • result = invoke( input, "toUpperCase", [] );
  •  
  • writeOutput( result );
  •  
  • </cfscript>

... you'll get the following ColdFusion error:

Could not find the ColdFusion component or interface Good morning Tricia . Ensure that the name is correct and that the component or interface exists.

That's a little bit of a bummer. But, fortunately, invoke() works with any non-String Java object where the invoke() signature is disambiguated. To see this in action, we can create an instance of the java.util.ArrayList class and then dynamically invoke the .add() method:

  • <cfscript>
  •  
  • collection = createObject( "java", "java.util.ArrayList" ).init();
  •  
  • // CAUTION: Using invoke() here is not strictly necessary; I'm just using
  • // it for demonstration purposes of the functionality.
  • invoke( collection, "add", [ "Happy" ] );
  • invoke( collection, "add", [ "New" ] );
  • invoke( collection, "add", [ "Year" ] );
  • invoke( collection, "add", [ "&" ] );
  • invoke( collection, "add", [ "Best" ] );
  • invoke( collection, "add", [ "Wishes!" ] );
  •  
  • writeOutput( arrayToList( collection, " " ) );
  •  
  • </cfscript>

When we run this code, we get the following output:

Happy New Year & Best Wishes!

Now, you don't really need invoke() in this particular circumstance; nothing is actually "dynamic". But, both the method name and the method arguments can be dynamic which is great because ColdFusion's "argumentCollection" functionality doesn't actually work Java methods. For example, if you wanted to try to run this code:

  • <cfscript>
  •  
  • collection = createObject( "java", "java.util.ArrayList" ).init();
  •  
  • collection.add( argumentCollection = [ "Hello world" ] );
  •  
  • </cfscript>

... you'll get the following ColdFusion error:

Cannot invoke method add on an object of type java.util.ArrayList with named arguments. Use ordered arguments instead.

However, we can easily pass in a dynamic argument collection to a Java method using invoke():

  • <cfscript>
  •  
  • collection = createObject( "java", "java.util.ArrayList" ).init();
  •  
  • methodName = "add";
  • methodArguments = [ "Hello World" ];
  •  
  • invoke( collection, methodName, methodArguments );
  •  
  • </cfscript>

Which works exactly as we'd hope!

Using invoke() with Java is not functionality that you need a whole lot. But, it can be really helpful in certain cases, like creating proxies to Java objects.




Reader Comments

@Rob,

invoke() is my new favorite method :) You don't need it all that often, but it just works good.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.