Category Archives: ColdFusion

re: CFMX Java-jock jihad

Geoff makes a couple blanket statements in his post about how the Java world doesn’t understand CFMX. I don’t agree with a couple of them:

· ColdFusion remains the only answer to making Java accessible to a mass of non comp-sci web developers — I don’t have a computer science degree, neither do 3 of the other 4 developers at Mindseye (all of whom have written Java applications and all of who have spoken at DevCon) and I’ve created a couple sites using Java & JSP technology so to say that non comp-sci web developers can’t understand Java is patently incorrect. I think it also bears mentioning that Java is considered by some to be a language for the masses:

The advantages of Java is that it easily serves as a lingua franca – everyone can read a Java program and understand what is going on…“,

· …most Java developers fail to see where CFMX fits into their world of programming… — Why should they care? There are a number of other scripting languages that work with Java, PHP being one of them. Java developers have enough to worry about… they’re too busy choosing between web frameworks (struts, tapestry, webwork2), persistence models (obj, castor, jdo..) and templating mechanisms (velocity, cocoon..). It’s commonly mentioned/demonstrated that ColdFusion is easy by showing how few lines it takes to query a database, but has anyone ever asked an enterprise Java developer how many queries they put into a JSP? .

With that said, I think that Geoff has the right attitude, starting a “.. post-positive campaign highlighting CFMX/Java symbiosis” is a great starting point. Go one step further though. Build a J2EE application, learn Struts, use OJB. Geoff claims that J2EE people don’t understand CFMX. How well do CFMX people understand J2EE?

Java Collection Types & ColdFusion

At work one of our developers is programming an ecommerce store against a Java API written by a third party. Said Java API returns a TreeMap object from a method and when you try to access that TreeMap object in any fashion, you’ll get an error, specifically:

“Error casting an object of type java.lang.Integer to an incompatible type. This usually indicates a programming error in Java, although it could also mean you have tried to use a foreign object in a different way than it was designed.”

What we’ve concluded is that ColdFusion attempts to cast any and all Java classes that implement the Map interface to:

coldfusion.runtime.Struct

which is of type java.util.Hashtable. Unfortunately, a TreeMap uses an Object (in this case an Integer) as the key. ColdFusion structures can only use strings as the key. The takeaway is that this is a ‘feature’ of ColdFusion, it’s nice that it attempts to transform collection type objects into the native ColdFusion structure type. In this specific case, it’s more of a hindrance. The workaround is to create your own Java wrapper that takes the TreeMap, loops over all the keys, inserting each into a Vector and then return the Vector to ColdFusion, which turns that into a structure.

In case you don’t feel comfortable going to sleep at night without seeing the code, here’s an example Java class that returns a simple TreeMap:

import java.util.*;
public class TreeMapTest {
   public static TreeMap getTree() {
      TreeMap t = new TreeMap();
      t.put(new Integer(131000), “product”);
      return t;
   }
}

Compile that and then drop it into your [cfusionmx]\wwwroot\WEB-INF\lib\ directory. You can use this script to test it:

<cfscript>
   tmt = createObject(“java”, “TreeMapTest”);
   WriteOutput(“tmt is of type ” & tmt.getClass());
   treeMap = tmt.getTree();
   WriteOutput(“treeMap is of type ” & treeMap.toString()); // you get an error here
</cfscript>

I’d be very very interested in hearing about any ways that you know of to get around something like this without having to write a wrapper class. And for you Macromedia ColdFusion guys, it might be a nice (albeit probably rarely used) feature to be able to maintain the Java type of an object by using some function, ( ie: maintainType() or some such).

By the way, if you’re interested in knowing more about using Java and ColdFusion together, Terry Ford has written a great article here entitled “Using Java and J2EE Elements in ColdFusion MX Applications”.

ColdFusion Whois client using Jakarta Commons/Net lib

Doug posted a query on the cfguru list asking how he might retrieve whois information using ColdFusion. I mentioned that there are numerous tags (search on google if you want to see them), but that it’s pretty easy to do within ColdFusion if you drop the Jakarta Commons/Net jar into your ColdFusion lib directory (cfusionmx/wwwroot/WEB-INF/lib/):

<cfscript>
  whois = createObject(“java”, “org.apache.commons.net.WhoisClient”);
  whois.init();
  whois.connect(“192.149.252.43”); // whois.arin.net
  WriteOutput(whois.query(“204.212.42.4”)); // your random ip address here
  whois.disconnect();
</cfscript>

Note that the whois service works over port 43, so your server must have outbound access to port 43 (if you’re accessing a server outside your own network, performance would presumably be much better if you ran your own whois server internally).

Calling Java Constructors with ColdFusion

I mentioned yesterday that Sam posted some great code that lets you upload files to ColdFusion without using CFFILE. His code can be shortened considerably with the use of the init() method:

<cfscript>
fileAsString = “”;
fileReader = createObject(“java”, “java.io.FileReader”);
fileReader.init(form.upFile);
bufferedReader = createObject(“java”, “java.io.BufferedReader”);
bufferedReader.init(fileReader);
try {
   do {
      fileAsString = bufferedReader.readLine();
      processLine(fileAsString);
   } while (true);
} catch (coldfusion.runtime.UndefinedVariableException e) {
// this indicates end of file, ok to ignore error
}
</cfscript>

Basically, you use the CreateObject() function to get a Java object. At that point, you can call static methods on the object or you can use the init() method to call the constructor of the Java object, which I’ve done above, ie:

// get a FileReader object
fileReader = createObject(“java”, “java.io.FileReader”);
// call the FileReader object constructor
fileReader.init(form.upFile);

If you’re curious about this kind of stuff, you should check out the article on Java, ColdFusion MX and Lucene integration I wrote for the July issue of ColdFusion Developer’s Journal, due to hit the stands anytime now.

Uploading files with ColdFusion

Sam posted some CF code that gives you the ability to upload a file to a web server without using CFFILE (ie: he uses Java instead): Handling file uploads without CFFILE.

On a related note, Oreilly has an article (Using the Jakarta Commons) that (will) introduce(s) each component in the Jakarta Commons library. Probably would have been better to use the tried and tested FileUpload component from the Commons lib, but that would have required the jar file be present in ColdFusion’s classpath.

Using Sockets in CFMX

I’ve read emails [1] [2] from a couple different people on the various email lists that CFMX can’t use sockets…. which is true in the sense that CFMX doesn’t have a <cfsocket> tag, but not true in the sense that you can’t easily use sockets in ColdFusion. I banged around this morning for a bit and came up with this example, which does an HTTP request of www.mindseye.com using a java.net.Socket object and then loops over the returned headers and prints them out to the screen:

<cfscript>
// get a socket object
socket = CreateObject(“java”, “java.net.Socket”);

// call the Socket constructor
socket.init(“www.mindseye.com”, 80);

// get a PrintWriter object
printWriter = CreateObject(“java”, “java.io.PrintWriter”);

// call the PrintWriter constructor
printWriter.init(socket.getOutputStream(), true);

// get an InputStreamReader object
inputsr = CreateObject(“java”, “java.io.InputStreamReader”);

// call the InputStreamReader constructor
inputsr.init(socket.getInputStream());

// get a BufferedReader object
input = CreateObject(“java”, “java.io.BufferedReader”);

// call the BufferedReader constructor
input.init(inputsr);

// request the homepage
printWriter.println(‘GET /index.cfm’);
      
// loop over result by reading line by line
run = true;
while (run) {
   // read the result line by line
   resultLine = input.readLine();
   if (len(resultLine) GT 0) {
      WriteOutput(“Header: ” & resultLine & “<br />”);
   } else {
      run = false;
   }
}   
</cfscript>

You could easily modify this to write xml to a server socket:

printWriter.println(‘<order orderType=”quote” customerType=”RETAIL” orderNumber=”1234″ orderDate=”2003-03-21″>’);
printWriter.println(‘<shipment ID=”1″ city=”Boston” state=”MA” zip=”02210″>’);
printWriter.println(‘<line_item ID=”1″ SKU=”18JK23″ category=”GSHOE” quantity=”2″ total=”39.90″ />’);
printWriter.println(‘</shipment>’);
printWriter.println(‘</order>’);

or do a variety of other useful things like send SMTP email, do DNS lookups, or send SOAP packets.

Sharing session data between ColdFusion and J2EE components

Informative article on developerWorks titled Together at last: Sharing session data between ColdFusion and J2EE components. After you read that article, read my notes on creating session listeners for CFMX. I show you how to capture CFMX sessionOnStart and sessionOnEnd events using servlet listeners.

I little birdie told me that sessionOnEnd and sessionOnStart events were coming in Red Sky, but I’m not in the beta program so I wouldn’t know…

Server-Side Flash Detection Using BrowserHawk @ DEVNET

I wrote an article for Macromedia Devnet which was just published today! Check it out here: Server-Side Flash Detection Using BrowserHawk. If you’ve never used BrowserHawk before, it’ll be a good introduction. However, if you’ve used it with ColdFusion, you should definitely read it, I was able to use BrowserHawk 4J (the Java version) with CFMX rather than using the ASP bridge (which was and is required if you want to access the extended properties of BrowserHawk in versions of ColdFusion prior to MX).

I should thank Shena at my work for bringing it up as an option (she contacted Macromedia originally), thanks Shena!