Category Archives: ColdFusion

CFX_LUCENE

I mentioned Lindex (described as a “… high performance, full-featured text search engine that allows developers to create document collections for easy indexing and quick searching” two days ago. After inspecting it a bit further, it looks like it offers an interface for developers to create and maintain Lucene indexes using ColdFusion (and I’m guessing allows them to search indexes as well), which is a nice feature.. I’d love to see it.

Anyway, inspired by Lindex, tonight I hacked together a Java CFX tag that closely mimics the the <cfsearch> tag using Lucene as the search engine. You can download the Java source here [ update 11/04/2003: Nick Burch from torchbox.com sent me an updated version that “behaves better under error conditions and … the command line debug now works“, thanks Nick!, clicking on the ‘lucene.java’ link above will download the updated version ].

To compile it, you’ll have to add both the cfx.jar file (usually in \CFusionMX\lib\cfx.jar) and the lucene.jar (get yours here) file to your classpath manually or specify them at compile time. If you’re compiling from the command line, it might look something like this:

$ javac -classpath c:\cfusionmx\lib\cfx.jar;c:\lucene\lucene.jar lucene.java

After you compile the class, you’ll need to

a) copy it to a directory that ColdFusion is aware of (ie: /cfide/administrator/ –> Java and JVM –> Class Path)

b) add the lucene.jar to the Class Path mentioned in ‘a’

c) register the CFX in the ColdFusion Administrator (/cfide/administrator/ –> Extensions –> CFX Tags. Click on ‘Register Java CFX’. The tag name should be ‘cfx_lucene’, the class name should be ‘lucene’.

d) restart CFMX.

e) and finally, create a .cfm page and add this script:

<cfx_lucene
  query=”r_query”
  indexName=”C:\hosts\cephas.net\wwwroot\blog\index”
  startIndex=”1″
  maxPage=”10″
  queryString=”java”>

The above script presumes that you have a Lucene index already created in the directory ‘C:\hosts\cephas.net\wwwroot\blog\index’, is looking for the keyword ‘java’, and will return a ColdFusion query object to the template with the columns ‘title’, ‘url’, and ‘summary’.

To see the results, you can dump the CFDUMP tag:

<cfdump var=”#r_query#”>

Caveat: It’s 1:42amEST so I’ve done no testing on it and it has no interface (like I’m sure Lindex does). Use at your own risk. If you do use it, please keep my name/email in the source somewhere and remember to thank Joe for the idea. Enjoy!

CFMX & HttpServletRequest/HttpServletResponse

I’m doing some research for an article I’m writing for Macromedia Devnet (hopefully to be published in May or June). I won’t go into the details of the article, but part of it deals (tangentially) with CFMX and Java integration. Specifically, I’m using CFMX to call a relatively simple Java API that consists of a couple methods, ie:

doSomething(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res, long someObject)

Looks pretty imposing doesn’t it? It’s actually pretty easy to call using CFMX.

<cfscript>
myObject = CreateObject(“java”, “com.thirdpartyApp.OtherClass”);
// retrieve the long value from the third party class
t = CreateObject(“java”, “com.thirdpartyApp.Class”);
longValue = t.SOME_CONSTANT;

// get a javax.servlet.http.HttpServletRequest object from CFMX
req = getPageContext().getRequest();

// get a javax.servlet.http.HttpServletResponse object from CFMX
res = getPageContext().getResponse();

myObject.doSomething(req, res, longValue);
</cfscript>

One interesting to note is that if you do getClass() on the req and res objects like this:

<cfoutput>#req.getClass()#</cfoutput>
<cfoutput>#res.getClass()#</cfoutput>

above you get the following class names:

req = jrun.servlet.ForwardRequest
res = coldfusion.jsp.JspWriterIncludeResponse

and although they don’t look like javax.servlet.http.HttpServletResponse and javax.servlet.http.HttpServletRequest objects, they actually extend the javax.servlet.ServletRequestWrapper and javax.servlet.ServletResponseWrapper classes, which are wrappers (as their names imply) for the javax.servlet.ServletRequest and javax.servlet.ServetResponse interfaces.

Anyway, interesting journey.. great help from Sean Corfield for his post about the getClass() method you can use to find out the type of an object and to Charlie Arehart for his comprehensive Java/CFMX archive.

Web.config vs. Application.cfm

In response to my post about the web.config file in ASP.NET, Ray asked how this was any different from Application.cfm in ColdFusion land. I think that it’s very similar, but there are some things that are better about web.config than Application.cfm.

First, and I think most importantly, web.config is a configuration file and a configuration file only. I’ve seen ColdFusion applications that use Application.cfm for security, some to include the header, some that contain database connection strings, some that contain UDF’s, etc. etc… Application.cfm is more flexible in that sense, but as always, that flexibility comes at the cost of misuse. There is no standard way of providing configuration information to a ColdFusion application.

Second, because web.config contains only XML, you can use your favorite XML parser to create and edit your configuration file. You could programatically generate your configuration file if necessary, while an Application.cfm would require a custom script to be written to first parse the file and then another script to write out the file.

Third, web.config files can be included in multiple directories on an application and inherited. You can include Application.cfm files in multiple directories, but you don’t get inheritance unless you explicitly include the parent level Application.cfm.

Fourth, you can programmaticly access configuration information about the current application without reading web.config. You can’t do this AFAIK in ColdFusion. For instance, let’s say that I have an Application.cfm that includes the following tag:

<cfapplication name=”myApplication” clientmanagement=”Yes” sessionmanagement=”Yes”>

and then somewhere later I wanted to know if sessionmanagement is enabled. How would I do that? Can you? Again, as far as I know, you can’t get that information without parsing the Application.cfm and looking for sessionmanagement=”true”. In ASP.NET, I write a simple line of code:

String sessionMode = Session.Mode;

where Session.Mode has the possible values of Off, Inproc, StateServer, and SQLServer.

I think something like what web.config provides would be a really nice addition to Application.cfm. Maybe Application.cfm just stays as it is and we get Application.config in addition…. maybe it’s better that Application.cfm goes away.

XML to CFC Mapping Tool?

Ray asked during our developer meeting today if .NET had any tools like JAXB. The Soapsuds Tool looks to be similar, although it certainly doesn’t appear to have as many features. But I think Ray was asking the wrong question. A CFC is approximately equal to a JavaBean in structure, so where JAXB for ColdFusion? Who’s creating a CFC generation tool? CFCZone.org would be the reasonable place to start but they’re still in startup mode (ie: no content). XML parsing is certainly easier in CF than it is in Java, so maybe it’s a moot point, but nonetheless it could be helpful to have a XML to CFC generator.

Mintz Levin dot com launch

So after about 12 hours of load testing and final preparations, I’m proud to say that the 2003 version of the Mintz Levin site is now up and running. The site uses web services for publishing information from the staging site to the live site, isapi_rewrite to provide search engine safe urls and is probably the latest revision available of the MINDSEYE CMS framework we’ve been developing internally for the last couple months.

If you read my previous posts about full text searching and the speed (or lack thereof) of Verity, you’ll understand why today we actually ripped out the Verity searching and replaced it with the Full Text Searching engine available in SQL Server. A couple things lead to that decision.

First, I couldn’t get anything faster than 250ms per Verity search on a (admittedly slow) single processor 500mz Pentium III. Since the site wide search page allows you to search up to 9 collections (and filter down within those sections for a more fine tuned search), the search page was taking upwards of 2 seconds to execute, which caused the machine get overwhelmed when doing anything more than a couple simultaneous users. Performance monitor would show the processor pegged at 100%, cfstat would show requests being queued and the average request time rapidly growing. After replacing the engine, we got the request time down to (in some cases) 16ms and cf didn’t spike the processor. In fact, we loaded the box up to 150 concurrent users (using Apache JMeter which is a great tool for doing cheap load testing, check it out sometime) with no issues (mind you, it’s a single processor 500mhz) . Not bad.

Second, SQL Server Full Text searching gave us more flexibility in searching; if I wanted to order the searches by datecreated or by something other than label or relevance, we simply added an ‘order by’ to the sql query.

Finally, because the SQL Server Full Text engine runs within a cfquery, you can add the cachedwithin attribute to the query to get the results directly into RAM. Verity doesn’t have a cachedwithin attribute, the only way to cache the results would be to stick the resulting query into application or server scope, which by itself isn’t all that bad, but just requires more coding than simply adding an attribute to a tag.

The only time I might use Verity (ie: where SQL Server Full Text Searching would not work) would be where I needed to index the file system (ie: html files, pdf files, word files) or where I needed to spider a site. However, even here, if you have the time to write extra code, it might make sense to use a freely available spider or text extraction tool to read documents on the file system system or spider the site and then store the resulting information in SQL Server as text. SQL Server Full Text Searching is obviously tied to a MS/Windows environment but I haven’t yet looked at how MySQL handles full text searching, although I know that Maia has done some work with it on nehra.com. I’d be interested in hearing about anyone elses’s experience with full text searching using MS SQL, MySQL or Verity. If you’re reading this post and are having issues with Verity and you don’t have access to MySQL or SQL Server with full text indexing, you might look at writing a CFX that wraps Lucene (an idea that Joe commented on).

Update: David and Ray sent a couple links:

Building Search Applications for the Web Using Microsoft SQL Server 2000 Full-Text Search [source]

Determining Current Version of CFMX [source, source]

new Macromedia.com

So the new Macromedia.com site went live yesterday, lots of reaction on the various lists I’m on to it. Notably, very few were positive, most were bashing the use of Flash or the speed or [insert pet peeve here]. How about a round of applause for pushing the envelope and drinking your own medicine? They’ve just converted an enormous site (really a combination of two distinct companies just a short time ago) into a massive rich internet application. Congratulations on a job well done! [via JD on MX]

using Verity and ColdFusion MX

Spent all day yesterday battling last minute emergencies for a site that’s about to launch. One of the things ‘problems’ was the speed, or actually the lack thereof, of full text searches using Verity and ColdFusion MX (documentation here). The site I’m working on has 9 full text collections (each one representing a different area of the site) and includes multiple forms allowing for full text search. One of these forms actually searches all 9 collections and returns results. In my testing, I couldn’t get any better than approximately 250ms per search, which meant that the search would take a mininum of 2.250 seconds, which isn’t acceptable at this point. I did optimize (multiple times) the Verity collections, many thanks to Geoff Bowers for this great post on ‘Verity Optimisation‘ (even if they do spell it wrong over there), as well as for his help offline. Geoff mentioned that my best bet would be to use K2, but it looks like we’re not going to be able to move to that before launch. Couple interesting things came out of an internal discussion about using K2 within CFMX (mainly from Ray Camden, thanks Ray!):

a) K2 reads in the collections at startup and apparently will not see updates to its’ collections until after restarted. Anyone have any official documentation that says that? (update: I do see this note: “Macromedia does not recommend running K2 Server as a Windows service. You must stop the service before you modify or delete collections registered with K2 Server. You must then remember to restart the service. You must also verify that the vdkHome information in your k2server.ini file is uncommented-that is, it has no leading pound (#) signs-and points to the correct location of the common directory.“)

b) because of a. above, you should probably restart K2 using cfexecute after the collection has been updated or at a set time/schedule using a Scheduled Task

c) because of b. above, there is a handy function ‘IsK2ServerOnline()‘ that you can use to determine whether or not the server is online, and if not, gracefully handle the error condition.

Create, Retrieve, Update, and Delete in ColdFusion

Mike has a great little tool running over on his site that does creates crud for you (where CRUD stands for Create, Retrieve, Update, and Delete). In another sense, he’s a couple steps away from creating an object-relational mapping tool similiar to what some open source Java tools do.
Mike, go one step higher and think about your data as an object and dynamically create CFC’s with the proper methods for creating, retrieving, updating, and deleting. This would mean that other developers using your system could use code that looks like this to create an event (or news or press release… given that MB’s system first created a table for an event and then created a CFC called event):

myEvent = createObject(“component”, “com.michaelbuffington.event”);
myEvent.setId(variables.id);
myEvent.setLabel(form.label);
myEvent.setStartDate(form.startDate);
myEvent.update();

Now other developers on your team a) don’t have to know what the names of the db tables are, b) you don’t have to worry about having multiple update queries (some of which might be buggy) and c) it’s just plain easier than writing

<cfquery name=”updateEvent” datasource=”#request.dsn#”>
update event set label = ‘#form.label#’, startdate = #form.startdate#
where id = #form.id#
</cfquery>

Other benefits to using a CFC that does your create(), update() and delete() for you: a) you can insert logging statements into your delete() and update() methods so that all updates and deletes are logged to the file system. I had a system setup like this on the footjoy.com project I worked on this past summer. It came in really handy when some of the content editors began putting in content… in fact they created over 100 pieces of content and then saved that content. Only the update() statement wasn’t working and wasn’t throwing a visible error to them. In my log file I had update statement so I only needed to parse out the bad code from the log file and drop that into Query Analyzer to get back all the updates. b) you can handle deleting objects on the file system that might be related to that piece of content. For instance, many press releases have a PDF file associated with them. If you used this:

myPressRelease = createObject(“component”, “com.michaelbuffington.pressrelease”);
myPressRelease.delete();

you could make sure that the press release PDF file was deleted from the file system at the same time that the press release is deleted from the database….

Anyway…. great job Mike! Looks like a great tool!

Using Google & ColdFusion

I’m sure this has been on Macromedia’s site for a bit, but it’s an interesting article for two reasons:

a) I’ve never really looked into the CFX documentation, but it appears from this article that creating a CFX, at least in Java, is a snap. Basically you implement the CustomTag interface, which means you only have to write one method, processRequest(), which looks very much like the doGet() method of the HttpServlet. After that you can write to the screen (ie: out.println() in servlet land == response.write() in CFX land), create a Query object for a CF page to loop over, or simply set a variable and return that variable to the calling template (response.setVariable() which is probably very much like request.setAttribute() in servlet land).

b) Couldn’t the author have done everything in a CF script using createObject() rather than using a CFX?