[Looking for Charlie's main web site?]

Tools and Resources for CFers, Part 1: Now over 100 categories

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
As some may know, I keep a list of tools and resources of interest to CFers, to help you answer the questions, "what tools/resources exist to help with ...?" I started it several years ago but update it constantly, and it now has over 700 tools and resources in over 100 categories. I've decided to start offering each category as a blog entry. Below, first, are the 100+categories, to give you a heads up of what's coming.

The Categories

I've split the list into Resources and Tools. Sometimes it's not clear how best to categories some subjects, such as CFML Frameworks, CFML Engine Alternatives, Monitoring Tools/Services, Testing Tools/Services, Time Tracking/Invoicing Tools/Services, and Web Site Design Repositories, to name a few.

Again, I'll be offering here a blog entry on each of the lists as part of this series.

I definitely want to hear of any possible editions or changes. Otherwise, I hope people will get great value out of the lists.

PS Of course, don't miss Brian Rinaldi's excellent list of open source CFML products and projects. I don't limit mine to just things written in CFML (nor indeed just open source), and of course I show more than just tools but also resources. For those interested, I discuss the differences, and indeed how I link to his list often from within mine, in a section of my list. They complement, rather than compete with, each other.

Revisiting CF/Java integration

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
On a mailing list, someone asked about running/integrating Servlets, JSPs, Struts, and EJBs in CF. This is one of those topics that was discussed a lot when CFMX came out, but those who didn't switch at the time may have missed out.

I thought I'd share here my answer to his question (pointing out several resources for him to learn more), in the hope that it may help others also who may only now be considering such integration.

Since he was already familiar with running JSPs on CF, but some readers here may not be, I'll start with just a quick point about that, then I'll offer what I replied to him.

CF and Java Integration

It may be important to clarify that technically, it was CF 4.51 that first afforded the option to integrate with Java (including EJBs). Though CF then wasn't built upon Java, you could point to a JVM in the CF Admin and various CF tags and functions afforded some Java integration.

CFMX 6, however, was not only only built upon Java but the Enterprise (and Developer) edition specifically added the ability to run JSPs and servlets directly within CF. More than that, there's some significant integration possible.

In the case of JSPs, you could just drop them into the same code directory with your CFML templates. Servlets take a little more work, as explained in my reply to the gent's email, below. He had been reading a JSP/servlet book and wanted to know how to run the latter, especially, on CF, as well as how to integrate with the Struts framework:

I hope I can help and I think you'll find I have good news.

You mention looking at a book on JSPs and servlets, and you ask how to implement them (and JSPs) in CF. Of course, that book won't help with that--but neither really will the CFML Reference (or a site like CFQuickdocs), if you may have looked that. You need to look at the ColdFusion Developers Guide in the CF docs (http://livedocs.adobe.com/coldfusion/8/htmldocs/Part_4_CF_DevGuide_1.html), or any CF books out there. The CF manual has a chapter specifically on this topic: Integrating J2EE and Java Elements in CFML Applications.

For instance, that chapter clarifies that to run a servlet called HelloWorldServlet, you put the servlet .java or .class file in the [CFserver]/WEB-INF/classes directory and refer to the servlet with the URL /servlet/HelloWorldServlet. It also discusses sharing data between CFML and such JSPs/servlets. You can even use JSP custom tag libraries directly within CFML, and lots more. And yes, the docs show (briefly) how to enable EJBs and call them from CFML.

That said, the coverage in the docs may leave one wanting more, so you may want to consider other resources that discuss it more. There was at least one book focused on that, Reality Macromedia ColdFusion MX: J2EE Integration. There were also lots of talks and articles back in the 2002 timeframe, when this stuff really took off with CFMX (though Java integration was added back in CF 4.51, which added a means in the CF Admin to point to a JVM that CF would work with.)

For instance, I did lots of presentations on CF/Java integration (as did others, of course). If you visit http://carehart.org/presentations/, and search for java, jsp, or servlet filters.

Doing Struts is not discussed in the CF docs, but there was at least one DevCenter article that discussed it specifically: Streamlining Application Development Using Struts in ColdFusion MX.

It's interesting to see these recent questions about things that came out with CF 6--many shops either didn't move from 4/5 right away, or did but didn't take advantage of the new features. Folks in that position will then not have necessarily followed all the resources (books, technotes, blog entries, user group talks) that came out back then.

This is one of the reasons I keep saying that any topic on the CF Meetup is welcomed. Not everyone needs only to learn new stuff, many need to learn what may seem "old" stuff. It's also the reason why I keep pointing to articles and talks I did in the way past. :-)

Though he didn't ask about it, of course also since CF 6 you 've been able to deploy CFML as a J2EE (or Java EE) web application/WAR or enterprise application EAR. That feature has improved from 6, to 6.1, to 7 (and of course is still possible in 8).

Certainly, if you're a shop that has any Java folks--and especially if there's some strong desire to lean that way, and CF is still seen mistakenly as a proprietary island--it's important to be able to convey to them that your CFML app can be deployed as a pure J2EE web app (WAR/EAR), which is a form they'd expect.

I think all this would be a topic worth my packing together for an upcoming CF meetup session. Until then, again, anyone interested in the topics can see the resources mentioned above that I and others have written.

Some of my FusionAuthority Quarterly Update Tip Columns now available online

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Some may know that I'm a regular contributor to the FusionAuthority Quarterly Update. Besides occasionally writing feature pieces, I have a tips column on the back page(s) of every issue. I'd like to point out here that the fine folks behind the magazine (Michael and Judith Dinowitz) have released the first couple of tips as PDFs, available online for free:

http://www.fusionauthority.com/tipical-charlie/

And that's not a typo. I called it "*Tip*ical Charlie" as a play on words. The titles of the articles in those first two issues were:

  • Text File Processing (PDF)
  • How Can I Call Thee (CFC)? Let Me Count the Ways! (PDF)

Enjoy, and do keep in mind that this tips column is intended to benefit newcomers as well as more experienced folks. The rest of the FAQU articles do tend to be more intermediate/advanced.

You can also find the titles for all my other FAQU articles (indeed all I've contributed to any magazine) on my articles page, and you can find the titles of other FAQU articles by other authors on the FAQU site.

Want the whole FAQU issue(s) in PDF form?

But some will want more than just my tips articles in PDF form. Here's good news: if you've not noticed, you can also get complete back issues (also in PDF form) for 7.95 per issue, and in fact the first issue is offered for free.

I suspect that as time passes, we'll see more of my tips and indeed complete issues released for free. Thanks to all the folks behind the FAQU.

Bug with Query of Query: using LIKE incorrectly finds records with null values

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Someone reported on a mailing list that they'd noticed a mistake in the results of a Query or Query operation when using a LIKE. It finds a record whose value for the column is null, which is of course wrong (that doesn't match the LIKE pattern--indeed a null never equals or doesn't equal anything).

The problem can be worked around by adding "and column is not null", but it really surprised me (and him, obviously) to discover the bug. Maybe someone else has written of it before.

But I tested it in 8.01 and can confirm it's still an issue. While I've recommended that he file it as a bug, I wanted to share it here until it's resolved. Hope this may help someone. (If we're missing something, feel free to comment.)

Here's some code you can run which uses the example app database that comes with CF. See the comments for what's wrong:

<CFQUERY NAME="demoq" DATASOURCE="cfdocexamples">
   select * from employees
</CFQUERY>

<!--- note that by default, all records in the example employees table have values in all columns --->

<cfdump var="#demoq#" label="before insert">

<!--- insert a record with only one column (causing the others to be null)
--->

<CFQUERY NAME="insert" DATASOURCE="cfdocexamples" >
   insert into employees (firstname) values ('charlie') </CFQUERY>

<CFQUERY NAME="test2" DATASOURCE="cfdocexamples">
   select * from employees
</CFQUERY>

<cfdump var="#test2#" label="after insert">

<!--- do a Q of Q of that query, for a column which would have a null for that last added records, so you'd expect it not to find it --->

<cfquery dbtype="query" name="test3">
   select * from test2
   where department like 'Sales%'
</cfquery>

<!--- that record with the null value still shows up! --->
<cfdump var="#test3#" label="dump of Q of Q">

Again, the problem is that the record with the null value still shows up in the Q of Q result, and it definitely should not. A solution for now is that if you change the Where clause to "department is not null and department like 'Sales%'", then it properly does not show the null-valued record(s) anymore.

(If anyone plays with this on their own code, note as well that Q of Q is case-sensitive, so no records would be found at all if you mistakenly used 'sales%' rather than 'Sales%', above.)

Anyone know where I can find a recorded presentation about ...?

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I saw a question on a CF list today, where someone was asking whether anyone knew of a recorded presentation about a particular topic. That made me think it might be time to remind the community of my UGTV site:

http://www.carehart.org/ugtv/

There you can find over 200 recorded presentations from nearly 150 presenters, totaling 220+ hours of video, all for free, and searchable, with RSS feeds, including RSS feeds based on your search criteria.

New recordings are being added all the time. Indeed, I've been thinking also of starting to publish a weekly summary of submissions here on my blog, for those who don't think to get the RSS feed.

Bloggers: validate your feed on new entries, or you and your readers could suffer. Here's how

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Have you ever found (as a blogger or as a reader of a blog's feed) that sometimes it seems the feed just seems to stop working? It could be that it's become invalid. Here's a tip.

Bloggers: you really should validate your feed on every new submission. You never know when some special character you used (or copy/pasted from elsewhere) might make your feed invalid.

In this entry, I propose a couple of possible solutions, either that you may find or that you can easily add to your own blog.

Validating your feed. Does your blogging tool do it?

I imagine some blogging tools may even offer this as a feature. It's easy enough to validate one's feed with a tool like http://feedvalidator.org/. You can easily validate your own by adding your URL with http://feedvalidator.org/check.cgi?url=yoururl. (Technically, the value of yoururl should be URLEncoded.)

Validating it yourself on each new entry

If your blogging tool doesn't do that validation for you, here's another thought: you could easily do it yourself. Here's code I use to check the feed whenever a new entry is made. It looks at the validation result and sends me an email if it fails, which has saved my bacon a couple of times:

<cfhttp url="http://feedvalidator.org/check.cgi?url=#urlencodedformat("http://carehart.org/blog/client/rss.cfm?mode=full")#" resolveurl="Yes">

<div id="content">

<cfif cfhttp.filecontent does not contain "congratulations">
   <cfmail to="myemailaddress" from="myemailaddress" subject="Your Blog's RSS feed has failed" type="HTML">
      <p><a href="http://feedvalidator.org/check.cgi?url=#urlencodedformat("http://carehart.org/blog/client/rss.cfm?mode=full")#">http://feedvalidator.org/check.cgi?url=#urlencodedformat("http://carehart.org/blog/client/rss.cfm?mode=full")#</a></p>
#cfhttp.filecontent#
   </cfmail>
   <cfoutput>
      <h4>Validation Failed</h4>
      For http://carehart.org/blog/client/rss.cfm?mode=full. Email sent to myemailaddress.
      <p><a href="http://feedvalidator.org/check.cgi?url=#urlencodedformat("http://carehart.org/blog/client/rss.cfm?mode=full")#">http://feedvalidator.org/check.cgi?url=#urlencodedformat("http://carehart.org/blog/client/rss.cfm?mode=full")#</a></p>
   </cfoutput>
<cfelse>
   <cfoutput>
      <h4>Validation passed.</h4>
      For http://carehart.org/blog/client/rss.cfm?mode=full passed.
   </cfoutput>
</cfif>
</div>

Of course, you could just drop that code into your blogging code if you're comfortable doing that.

Using your blog tool's Ping feature

But if you don't want to edit your blogging code, you could do this just as easily with your blogging tool's ping feature, if it offers one. These are more typically used to provide one or more URLs which the blogging tool will call when you offer a new entry, such as to notify blog aggregators of your new entry (rather than waiting for them to come back to find your entry eventually).

You could use that same feature have it go to a URL on your own site that runs the code above. That's what I do.

Is there a service doing this already?

I suppose someone could set up a service to do this, letting you pass in the URL and email addresses. For now, I'm not in a position to do that on my own server for others. One would need to be careful not to let this be abused in any way. I also imagine it could get used by a lot of folks.

I kind of wonder why some free service hasn't yet been created to do this. Surely someone could find a way to monetize it. :-)

Anyone know of such a tool?

Anyway, there's the idea and the code above, if it may help.

PS: This is more than just for bloggers

BTW, this applies to more than just blogs. Anything where you add items that offer an RSS feed to read them, this would make sense, such as podcasts, news items, and more.

In fact, I've been meaning to write this entry for a long time, and was actually motivated when I came across some failing OPML for one of the CF blog aggregators today. I dropped a note to the owner, letting him know that someone had slipped in a bad character when they'd entered a new feed to him. I suggested he could benefit from this idea (as would others), and that I'd blog about it. There you have it.

CF 8.01 includes licensed technology. Things that make you go hmm.

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
I happened to notice today that the 8.01 release notes end with this reference: "Portions include technology used under license from Autonomy", and later it lists "TVirtualStringTree". These made me wonder: who/what were Autonomy and TVirtualStringTree?

I did a little digging, and hadn't seen anyone else write about these (it seems) in the CF blogopshere, so I'll share what I found. They're nothing dramatic.

Autonomy=Verity

In the first case, I guess I just missed the news, but back in 2005, Autonomy acquired Verity. (Seems like the acquisition last month of MySQL by Sun. Doesn't appear to have been too significant in the grand scheme. The tools continue to be known by their former company names.) Also, more digging found that this had been mentioned in the 8.0 release notes as well, but I just hadn't noticed it. FWIW, there was no mention in the CF7 notes/docs that I could see.

TVirtualStringTree in Report Builder?

What about TVirtualStringTree? Well, that isn't as obvious. It appears to be a Delphi component, and the only thing I can think of that's written in Delphi that might have been updated for 8.01 would be the CF Report Builder. Perhaps Dean Harmon or someone else from Adobe can confirm that guess. It's not important, of course.

Just one of those "things that make you go hmm" (to the younger folks out there, that's a reference to a bit from the old Arsenio Hall show of the early 90s. Gosh, now I know how my parents must have felt when they'd talk to me about the the Jack Parr show, when I was a teen in the 70's!)

PS: Searching the CF blogs

BTW, I said I hadn't seen any mention of this in the CF blogosphere. Was I going only on my memory? Heavens, no. I don't at all claim to have read most (or even 10%) of all many, MANY blogs out there on CF. It's great that there are so many, and that we have so many CF blog aggregators. But even then, none let you search all the past blog entries (at least it seems to me, as I searched for some text on that entry in all the aggregators and none found it).

So how does one do a quick search of most CF blogs? Well, last year I created a Google Custom Search Engine I call CFSearch. It lets me (and you)search only CF-related blogs and other resources. There are other CF CSEs out there, and I wrote about them back when I created mine.

I make a bookmark link for my CSE so that I can do such a search easily. Hope you'll consider doing the same.

Helpful info on SQL Server Diagnostics: Part II

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Last week I pointed out a useful blog entry on SQL Server troubleshooting. Now there's a Part II, which addresses such things as:

  • Are there SQL batches that actually run for a long time?
  • Is there blocking in the database?
  • Are there any problems in the configuration options of SQL Server?
  • Is there a disk IO problem?
  • Are there any indications of memory problems?

Good stuff that even we CFers can benefit understanding. Again, while it's from a Microsoft support engineer who focuses on .NET debugging in her blog, there's really nothing about this blog entry or the last that's .NET specific.

CFMAIL being detected as spam? Some solutions for CF 6, 7, and 8

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Someone asked on a list about how to resolve the problem where messages sent via CFMAIL have a message-id value that can cause mail to be flagged as spam. I mentioned in an earlier entry how to solve this in CF8. In this entry, I offer a couple of solutions for CF 6 and 7.

To backup and explain the problem, some have lamented that in CFMX 6 and 7, CFMAIL used the name of your server where CF is installed, which might be something like "server1" or "bingo", as in:

Message-ID: <23070863.1197039960343.JavaMail.SYSTEM@Server1>

This might cause a recipient mail server to flag the mail as spam, if the mail server was a different domain name (like "yourcompany.com"). The bummer was that many found no way to fix this. Sure, in CF5 you could set it in a CFMAILPARAM to set a mail header, but CF 6 and above ignores that.

The good news for those on CF 8 is that a change makes the problem go away, which I talked about in a blog entry back in December.

But for those still on 6 or 7, I'd mentioned that there's an available code or (preferably) configuration fix to resolve the problem. Apologies for not posting it at the time, so here it is. I also explain what the issue is all about, for those not aware of it.

Simple CF5 solution doesn't work in 6, 7, or 8

First, let me point out that some may propose that one can just use CFMAILPARAM to set that message-id header, as was mentioned in this FAQ:

http://www.developer.be/index.cfm/fuseaction/faqDetail/FaqId/201.htm

Unfortunately, that's a very old FAQ and it no longer applies after CF5.

CFMX 6 (and 7 and 8) ignore that header you set and set the message-id themselves to the name of the physical server from which the mail's sent. Here's an example, from my laptop (which is named charlied620):

Message-ID: <23070863.1197039960343.JavaMail.SYSTEM@CharlieD620>

On your server, it could be that the problem is that the server is a real domain name, but it's not the same name as the SMTP server through which you're sending email via CFMAIL, and some servers won't let mail through with FROM addresses having a different domain name.

Why doesn't CF just use the SERVER set in CFMAIL or the CF Admin?

You might wish/expect it would just use name of the mail server as specified in the CF Admin mail server setting or the CFMAIL SERVER attribute, but it does not (at least, not prior to CF8, as discussed in my earlier entry.)

But while researching this problem for the person, I found this, where a very compelling solution was proposed. I tested it, and it does indeed work.

It turns out that you can get CFMAIL to use a specific mail server, either of 2 ways, for CF 6, 7, or 8 (again, on CF8, the easier solution is that I discussed in the earlier entry). Ken Smith of Adobe offered it also in this Adobe forum thread. If you make this change, either server-wide or per page/app, you will now find that the CFMAIL sets the message-id to use a desired servername.

Solution for 6, 7, or 8: Configuring it at CF Startup

If you're on a server where you want to change this for all CFMAIL (and javamail) done from within CF, you can change the JVM.config for your server to add this to the java.args line:

-Dmail.host=desiredservername

That java.args line is one long line. Don't introduce any line breaks. You need to restart the server after making that change. As always, when editing the JVM.config (in the runtim/bin directory of CF), make a backup first, because if you get it wrong, your server won't restart. (Or leave the file open and be prepared to do an Undo in your editor.)

But if you don't want to (or can't) mess with the startup file, or more important, if you are on a server where each app may need to do its own setting, you're not out of luck.

Solution for 6, 7, or 8: Changing it programatically

You can also make the needed change on the fly, programatically. You could issue this set of code just before your CFMAIL:

<cfscript>
sysObj = CreateObject("java", "java.lang.System");
sysObj.setProperty("mail.host", "desiredservername");
</cfscript>

I tried this per-page setting in in 6 and 7 and it worked fine. For CF8, the code will run, but it won't affect the CFMAIL for reasons I explain in the next section. But there's a real problem with this approach, if you're on a shared CF server. You're still setting the value for the entire CF server, but you're just doing it on the fly. It has at least a few problems you need to think about:

  • you'll affect all who use CFMAIL on this server (at least in 6, and 7, since CF8 ignores this, as discussed below)
  • you'll also affect anyone who uses Javamail on this instance of CF
  • and if someone else on the server issue the same code with a different server name, that of course would override your setting

There are a few things you can do to mitigate the problem, but they're not entirely perfect.

First, you could get the current mail.host value (in case it's different), then change it to what you want, and then change it back. You could do that with this code:

<cfscript>
   sysObj = CreateObject("java", "java.lang.System");
   // if there is no mail.host set already, this next variable simply won't be created. need to know that for later.    oldmailserver = sysObj.getProperty("mail.host");
</cfscript>

Note that if the mail.host property has not been set in the startup config or by someone else running such code, then the getproperty will return nothing, and the oldmailserver variable literally will not be created (a curiosity of working with some java methods).

Once you have the oldmailserver (or know that it did not exist), you can do the set of the property and the cfmail as above, then you could set it back with the following:

<cfscript>
// reverse the setting of the mail.host, so as not to affect others on this server if (not isdefined("oldmailserver")) {
   // if there was no previously set mail.host, remove the property
   sysObj.getProperties().remove("mail.host");
}
else{
   // set it back to what it was before
   sysObj.setProperty("mail.host", oldmailserver);
}
</cfscript>

There's still a problem. Because of CF's multi-threaded nature, it's entirely possible that between your setting the host and doing your CFMAIL, someone else could also set the mail server to something different. (This is called a "race condition".)

Now, Mr. Smith in the threads above suggested that you could wrap the code doing the change and the CFMAIL in a named lock, but that's an incomplete solution. It will prevent other other code (that ALSO does the same named lock) from running until yours is complete, but it won't help if others do the set of the property without bothering to use the same named lock (or use a differently named lock).

That's a frequent misconception about locks. They don't prevent other code doing what you're doing in the lock: they only tell other code that IS using the same lock not to run while this lock is held--and even then, only if you use an EXCLUSIVE lock, which he didn't indicate.

So the bottom line is that as useful as the feature is to set the property dynamically, it's fraught with peril in an environment where multiple apps may try to use the code. Only if you can guarantee that all use the same named lock will you be able to protect against this problem is held up while you have the value changed:

<cflock name="setmail-servername" timeout="10" type="EXCLUSIVE">

   <cfscript>
   sysObj = CreateObject("java", "java.lang.System");
   // if there is no mail.host set already, this next variable simply won't be created. need to know that for later.    oldmailserver = sysObj.getProperty("mail.host");
   sysObj.setProperty("mail.host", "desiredserver");
   </cfscript>

   <cfmail ...>
   ...
   </cfmail>
   
   <cfscript>
   // reverse the setting of the mail.host, so as not to affect others on this server    if (not isdefined("oldmailserver")) {
      // if there was no previously set mail.host, remove the property
      sysObj.getProperties().remove("mail.host");
   }
   else{
      // set it back to what it was before
      sysObj.setProperty("mail.host", oldmailserver);
   }
   </cfscript>
</cflock>

Now, someone may propose that all this could be wrapped up into UDFs or CFC methods, and perhaps it could, but since you need to do the setting of the value, and the mail, and the resetting of the value, all within a CFLOCK, it would be challenging to wrap all this up into a generically callable method (unless you wanted to pass in as well all the CMAIL attribute values and the body). Just seems not worth it, since this is a pretty esoteric problem and solution. But others can comment if they feel differently.

Solution for CF8 is much easier

All this is obviated on CF8, because it now properly uses the name of the server specified in the CF Admin mail server setting (or CFMAIL SERVER attribute, which overrides the CF Admin setting.) This is AWESOME news for those challenged by this, and hasn't gotten much press.

Now, what was the caveat I mentioned above? Well, if you use the approach of setting the mail.host servername in the java property, CF8 no longer pays attention to that. It JUST uses the CF Admin mail server setting, or the CFMAIL SERVER attribute. So that code above "won't work". It will work, but it won't affect CFMAIL. But that was a hack to work around CF not honoring these other attributes. I'm not surprised (or bummed myself) to see that it no longer regards the mail.host property for CFMAIL.

(I should say I'm saying this as of CF8. I've not tested it on 8.0.1.)

Some related notes

If you add the SERVER attribute, you may need to add the PORT, Username, and Password as well.

Here's a little bonus tip, in case you try to use the CFMAIL SERVER attribute for the first time on an existing CFMAIL tag to check this out. Note that using the SERVER attribute on CFMAIL requires you then to specify any other attributes required for the mail connection such as USERNAME and PASSWORD (if needed) and PORT (if not 25). What I mean is that it will no longer pick up the values in the CF Admin. If you override the SERVER, then you override the other config settings as well and need to specify them.

I'm not getting the emails now. Where are they?

If you make a mistake in your setting of the mail server arguments, then CF will move the failed emails to the [coldfusion]/mail/Undelivr directory where CF is installed. They're just plain text files. You can open them to see what got set and perhaps can figure out why they failed. You may also find information in the [coldfusion]/logs/mail.log.

When I look at mail in the spool, it looks fine (if I use CFMAILPARAM). Why doesn't it get through?

Don't be misled. The email you generate in CFMAIL may look fine in the [coldfusion]/mail/spool directory, but when it gets sent to the mail server, CF will change that message-id (and some other headers). You really need to look at the email as it's RECEIVED. You can't even look at the message in the Undelvr folder as an indication. It doesn't have those added headers.

So how DO I observe the mail headers?

You need to receive the email and then look at its headers. I'll show you how to do that in Outlook and gmail in a moment. Let me point out that it can be very englightening to view the message headers: not only the message-id but possibly also other headers as well as messages that CF, your mail server, or the mail server of your recipient may have added, which may include indications of whether your email was detected to be spam (perhaps by tools like SpamAssassin).

In Outlook, you can use View>Options while reading an email, to see the values in the "Internet Headers" box of the window that opens. Scroll down in that to find the message-id and other headers.

In gmail, when you open the message, look to the top right of the pane showing your email, to the right of the indicator of the time the message was received. There's a drop-down box, with options like "reply" and "forward". Choose "show original". That will show the complete message including all the headers at the top.

Other CFMAIL alternatives/replacements

Finally, I'll point out that if you run into other problems with CFMAIL, there are always alternative CF mail server solutions, like those I list in the "CFMAIL replacement/enhancement tools" section of my "Tools to Consider for CFML developers" page.

Hope that helps some.

Helpful info on SQL Server Diagnostics

Note: This blog post is from 2008. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
Here's a useful blog entry, "What if I suspect that my performance problem is in SQL server?". It's easy to blame CF for performance problems, but sometimes the problem is in the database--and it could be configuration, or database setup, all in addition to your own (or someone else's) SQL coding.

The entry focuses on using the tools known variously as PSSDIAG and SQLDIAG, either built-into SQL Server 2005 or available for free download for older editions, and it does a nice job of walking through it in a friendly way, with screenshots and more.

The entry is on the blog of Tess, a Microsoft support engineer, called If broken it is, fix it you should. While the majority of her entries are on .NET, this was a guest blog entry with a SQL Server support engineer. Despite her blog being mostly about .NET, there are occasional gems like this which are of equal value to CFers.

More Entries

Copyright ©2024 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the html in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting