I am becoming increasingly interested in the Java world that lives below the surface of ColdFusion. She seems like a really sexy girl and I like playing with her bits. The problem is, I don't really know what is available. You can call GetMetaData() on objects and it gives you some insight, but not everything you need to know. To overcome the limitation of GetMetaData(), I have developed two functions to help in my exploration:
GetJavaClassMethods()
GetJavaClassMethodParameters()
While the first method above is the *real* method of use, let's look at the second method first:
This method takes only one argument, a Java method definition. It takes this definition and pulls out the parameters that need to be passed in and returns them as a comma-delimited list. This is sooo key when compared to GetMetaData() because it shows you how overloaded methods are different from one another.
Let's take a look at the method:
Launch code in new window » Download code as text file »
This function might return, as an example, something like "int, java.lang.String". This would denote that to properly call the Java method, you would need to pass it an integer and a string value (in that order). Remember to use JavaCast() when calling Java methods.
But, that's just a small part of it. Let's take a look at the parent function:
This takes a ColdFusion object and returns all of its available Java methods. I don't think all of these can be used exactly - it takes a bit of trial to get it right. The method list is returned in a query that has both public methods AND constructors as well as the parameter list discussed above and the return types.
Launch code in new window » Download code as text file »
As you can see, the Method Query is built from the ground-up based on the constructors and then the public methods of the Java class that lives under the passed-in ColdFusion object. To see this in action, the following code:
Launch code in new window » Download code as text file »
... would produce the following dump:
| | | | ||
| | ![]() | | ||
| | | |
Let's compare that to the standard GetMetaData() dump:
| | | | ||
| | ![]() | | ||
| | | |
How cool is that?!? My method list is not only alphabetically listed (no worries, it was my pleasure), it shows you what kind of arguments you need to send in. No more guessing! Let's the exploration begin!
Download Code Snippet ZIP File
Comments (5) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Ask Ben: Extracting Parts Of An Email Address In Javascript
Michael Dinowitz On Type Validation And Going To Hell
Ben, I wanted to let you know I adapted these functions into cfscript (what can I say, I dig the quasi-ECMA thing) and they have been a life saver. I'm working on a gi-normous project to bridge our company's CF-based software with a third-party vendor's system via their web service. Unfortunately, the 3p's documentation is Cruddy McCrap. Their sample code and docs are often out of date or just plain wrong. Now I can see precisely what parameter types are expected. We'll see if this works in comment form, but here it is (if you're curious about some of the variable names I often prefix my variables with a letter to indicate the expected datatype s=string n=numeric k=struct etc)...
<pre>
function getJavaClassMethodParameters(sMethod) {
//Returns the arguments for the given Java method call.
var kLocal = StructNew();
var i = 0;
kLocal.Parameters = Arguments.sMethod.GetParameterTypes();
kLocal.ParamList = "";
for (i=1; i lte ArrayLen(kLocal.Parameters); i=i+1) {
kLocal.ParamList = ListAppend(kLocal.ParamList, kLocal.Parameters[i].GetName());
}
kLocal.ParamList = Replace(kLocal.ParamList, ",", ", ", "ALL");
return kLocal.ParamList;
}
function getJavaClassMethods(oObject) {
//This takes an object and returns a query of all the available Java methods including constructors.
var kLocal = StructNew();
var i = 0;
kLocal.MethodQuery = QueryNew("name, returntype, parameters, isconstructor");
try {
kLocal.ClassConstructors = Arguments.oObject.GetClass().GetConstructors();
}
catch (Any e) {
kLocal.ClassConstructors = ArrayNew(1); // no constructors found.
}
try {
kLocal.ClassMethods = Arguments.oObject.GetClass().GetMethods();
}
catch (Any e) {
kLocal.ClassMethods = ArrayNew(1);
}
if (ArrayLen(kLocal.ClassConstructors) + ArrayLen(kLocal.ClassMethods) gt 0) {
QueryAddRow(kLocal.MethodQuery, (ArrayLen(kLocal.ClassConstructors) + ArrayLen(kLocal.ClassMethods)));
}
for (i=1; i lte ArrayLen(kLocal.ClassConstructors); i=i+1) {
kLocal.MethodQuery["name"][i] = kLocal.ClassConstructors[i].GetName();
kLocal.MethodQuery["returntype"][i] = Arguments.oObject.GetClass().GetName();
kLocal.MethodQuery["parameters"][i] = GetJavaClassMethodParameters(kLocal.ClassConstructors[i]);
kLocal.MethodQuery["isconstructor"][i] = 1;
}
kLocal.Offset = (i - 1);
for (i=1; i lte ArrayLen(kLocal.ClassMethods); i=i+1) {
kLocal.MethodQuery["name"][kLocal.Offset + i] = kLocal.ClassMethods[i].GetName();
kLocal.MethodQuery["returntype"][kLocal.Offset + i] = kLocal.ClassMethods[i].GetReturnType().GetName();
kLocal.MethodQuery["parameters"][kLocal.Offset + i] = GetJavaClassMethodParameters(kLocal.ClassMethods[i]);
kLocal.MethodQuery["isconstructor"][kLocal.Offset + i] = 0;
}
return getJavaClassMethodsQuery(kLocal.MethodQuery);
}
</pre>
Posted by Jeremy on Sep 27, 2006 at 11:16 AM
Oops...well so much for using the <pre> tag. :-)
Posted by Jeremy on Sep 27, 2006 at 11:17 AM
Jeremy,
Sorry it has taken me so long to comment on your stuff. I think it's awesome. I especially like the TRY / CATCH blocks you put in. I started to realize that some of these things do throw errors and I have been too lazy to fix it.
Well done dude, well done.
Posted by Ben Nadel on Oct 3, 2006 at 7:16 AM
Just to let you know in the first code block you don't need to do a replace on the delimiter to space it out. You can simply provide the comma and the space as the delimiter in the listAppend function call. For example, you could do just this: ListAppend("myString", myList, ", ") and it'll work just fine.
Posted by Javier Julio on Jan 27, 2007 at 10:45 PM
You are the man! Simple as that :-)
Posted by Boyan on Jan 28, 2007 at 8:44 PM