How Do I Call Methods On ColdFusion Components In Java

Posted October 9, 2006 at 6:16 PM

Tags: ColdFusion

I am experimenting with Java and ColdFusion and I am hitting a brick wall very quickly. As one of my first experiments, I tried to pass a ColdFusion component into a Java wrapper class. The idea was that method calls on the Java object would turn around and call those methods on the ColdFusion component. Now, I can pass in the object no problem. Storing it get's sticky. I am storing it as java.lang.Object since I can't store it as a ColdFusion class (don't have access to those class definitions).

I tried to call Invoke() on the ColdFusion component, but I am not sure how it is called. I tried sending the method name I wanted to call. I tried sending the method pointer that I wanted to call (as returned from the GetMethods() array). Nope, nothing but and ColdFusion errors.

I see that a component is of type coldfusion.runtime.TemplateProxy. Not sure what that is. I have found references to it on other sites, but nothing extensive.

What I want to do is something like this:

 Launch code in new window » Download code as text file »

  • public java.lang.String GetFirstName(){
  •  
  • // Call this method on the ColdFusion component
  • // object and return that value. This component is
  • // currently stored as java.lang.Object (this.Handler).
  • return(
  • this.Handler.GetFirstName()
  • );
  •  
  • }

As I said, this is not working... Anyone have any ideas?

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Oct 9, 2006 at 10:41 PM // reply »
2 Comments

I did a lot of playing around with this some time ago. First off, what you want to do isn't "really" possible. A CFC is not one java class, but a collection of classes. For an example look under your cfclasses directory (under coldfusion). Find a class in there that looks familiar and you'll see a class for the CFC and one for each method. That's right! A CFC method gets compiled down to one java class.

Furthermore, if you reflect the Template Proxy you'll notice that it has methods on named invoke. I assume these are what CF calls to invoke methods. However, I have no idea what arguments they accept (and I've tried quite a range of options!). Furthermore, this is unsupported and I think it would be a mistake to actually implement due to risk of these APIs changing in future versions of ColdFusion.

For assistance reflecting CF classes use this tool: http://doughughes.net/reflection/index.cfm?event=ReflectClass

It can be downloaded here: http://doughughes.net/includes/reflector/reflection.zip (Requires MG 1.1)

Now, if you're using an old version of CF 7 (I forget the exact version, but before the first big update related by Macromeda. 7.0.1?), you can read a blog entry I wrote that shows a method of using an undocumented feature (for that version - which existed at that time in both CF standard and enterprise) called the CFCProxy to execute methods on CFCs from Java. Here's the entry: http://doughughes.net/index.cfm?event=viewEntry&entryId=122. There's a lot of information in there, but if you look past the technique for embedding java classes in a CFC you'll find a Java class that can call methods on a provided CFC.

Now, the problem is that from what I've been told CF removed the CFC proxy in the standard version (a risk with undocumented features) and supposedly enhanced it for enterprise only use in the first major update after the release of MX 7. So, now (for whatever stupid bloody reason) only MX 7 Enterprise users are allowed to use the CFCProxy. This rather ticks me off, personally. I refuse to use any features that aren't stupidly compelling in CF that are enterprise only features.

Anyhow, good luck with your experiments with Java! This is fun stuff with CF/Java.


Oct 10, 2006 at 8:01 AM // reply »
6,516 Comments

Doug,

Awesome information... and horrible information :) Ok, so no worries. I just need to change the way I handle this stuff. The learning will continue.

I like that reflector object, it looks like it is doing a MUCH better job of something I wrote a while back:

http://www.bennadel.com/index.cfm?dax=blog:206.view

I will keep you updated.


Jul 3, 2007 at 6:59 AM // reply »
2 Comments

You can actually do this using the cfcproxy...

http://www.forta.com/misc/cfcproxy.htm


Jul 3, 2007 at 7:06 AM // reply »
2 Comments

You can actually do this using the cfcproxy...

http://www.forta.com/misc/cfcproxy.htm


Jul 3, 2007 at 7:12 AM // reply »
6,516 Comments

@Nick,

That looks very cool. But, it looks like the CFCProxy object can only be initialized via a file location. Is there a way to use the CFCProxy to invoke arguments on CFCs that were passed into a Java method?

Or am I totally misunderstanding something?


Mar 5, 2009 at 2:11 PM // reply »
27 Comments

Ben

Did you figure this out in the end?

I spent a fair bit of time a while ago calling methods on CFCs from Java in order to write a SAX parser I could use in ColdFusion. That was fairly straight-forward as everything was done in the same request to a CFM. I've now hit a dead-end when trying to call CFC methods from Java outside of a ColdFusion request.

If everything's going to be done on the same request, such as a CFM page creating a CFC and a Java object, then having the Java object call CFML methods in the CFC, I can mail you some code to show you how it's done using Java reflection.

I, however, will carry on investigating how to do it outside of a ColdFusion request...

George.


Mar 5, 2009 at 2:36 PM // reply »
6,516 Comments

@George,

I never got this working. I can easily call Java methods from within ColdFusion. But, I was never able to figure out how to pass a ColdFusion component to Java and then, within a Java class, call a method on the passed-in ColdFusion component. Have you been able to get that to work?


Mar 9, 2009 at 7:03 AM // reply »
27 Comments

Sorry for the late reply... didn't get an email when you posted a response and only just came back to check.

Yes, I managed to call functions inside a CFC from Java. That part is (relatively) straight-forward. I did it a different way to how it's described here, but Ben Forta released some documentation on how it's done using CFCProxy. See this page:
http://www.forta.com/blog/index.cfm?mode=entry&entry=A61BD06B-3048-80A9-EF15B0E3B096BFCD

The downside of using CFCProxy is that you'll need the developer or enterprise version of CF for it to work. If you've got the standard edition running on your production systems, you're on your own. I think my implementation will work even if you're using standard edition as the licence checks are done inside CFCProxy, which I don't use.

The whole topic of calling CF from Java is incredibly poorly supported by Adobe. In that article, Ben mentions that they're going to be putting up some proper documentation on the subject but there's still absolutely nothing on the Adobe site besides the patch notes. Poor show, Adobe.

The technique he describes will also create a new instance of the CFC each time. This may be fine under some circumstances but most of the time I've needed to do this, I need to call methods on a CFC I've already initialised, and now I need to do it outside of a page request as well. I spent nearly four days figuring out how to do this and I've now got it working by mimicking the CFCProxy functionality but providing it an instance of the CFC I've created already. Works fine but it's definately not going to be supported by Adobe, that's for sure.

When I get the time, I'd quite like to write a paper on everything I've researched to get this functionality working and all the bits and pieces I've discovered in the process.


Mar 9, 2009 at 7:06 AM // reply »
27 Comments

Accidentally posted before finishing!

I'll clean the code up a little this week and email it over to you so you can see how to call CFC methods from Java on an existing CFC from inside a request.


Mar 10, 2009 at 8:50 AM // reply »
6,516 Comments

@George,

Thanks for pointing me to the CFCProxy API. At least it gives some insight into all the casting that might need to be done. I am looking forward to seeing your work.


Mar 13, 2009 at 2:48 PM // reply »
1 Comments

I'm a ColdFusion newbie and my Java experience isn't up to Doug's. I need to call a CFC from an applet.

As I understand it, CFCProxy requires that the Java program calling the CFC must be running in the ColdFusion server's JVM? Obviously that wouldn't work for an applet.

If that's the case, perhaps I should fall back to WSDL or even AJAX calls?


Mar 15, 2009 at 8:37 AM // reply »
27 Comments

Eric,

For the most part, CFCProxy does indeed need to be running in ColdFusion's JVM.

I'd use web services in your case. Very, very easy to set up from your CF code and easy to call, too.

George.


Apr 15, 2009 at 12:04 PM // reply »
1 Comments

Hello George,

You mention in your post: I'll clean the code up a little this week and email it over to you so you can see how to call CFC methods from Java on an existing CFC from inside a request.

Is it possible to have a copy of the code you mention?
We would like to call CFC methods from external Java files too.

Regards,
Zoltan


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »
Nov 20, 2009 at 11:32 PM
Five Months Without Hungarian Notation And I'm Loving It
I've used headless camel case for years for not only ColdFusion variables, but also SQL tables and fields... pretty much everything involving code. I also subscribe to the "don't abbreviate and clea ... read »
Nov 20, 2009 at 11:00 PM
Five Months Without Hungarian Notation And I'm Loving It
@Marcel, Yeah, I always err on the side of longer but more readable variable names. As for the camel casing of CF methods and the headless camel casing of custom items, I get around this by always ... read »