Archive for the 'ColdFusion' Category

Using CFID and CFToken to jump between ColdFusion servers

Thursday, April 17th, 2008

In a couple application’s I’ve found it necessary to send a user to another ColdFusion server, but still maintain their current session. Usually this is for a payment gateway, or encryption process, or some other kind of functionality that only exists on that other server. In CF5 this was pretty straight forward. You set up both servers to access the same client variables database, then provide an HTML link (or a cflocation tag) that jumps the user to the other server, keeping their CFID and CFToken on the URL. The second server will see those URL values and use them, instead of generating new CFID/CFToken values as it normally would. I had both servers setup something like this:

<cfapplication name="myapp"
setclientcookies="Yes"
clientmanagement="Yes"
clientstorage="MyClientVarsDatasource">

This is a little different in CFMX onward. Having the url tokens on the URL still prevents ColdFusion from creating them, and it instead uses the ones provided for the current request - just like we want. But it does not send cookies to the client with these tokens, even though we are specifying setclientcookies=”Yes” in the cfapplication tag (or Application.cfc). So while first page on the new server works (because the CFID/CFToken are still on the URL), if they click a link to access a second page they will have lost their session.

The way to fix this to turn setclientcookies off and set the cookies yourself:

<cfapplication name="myapp"
setclientcookies="No"
clientmanagement="Yes"
clientstorage="MyClientVarsDatasource">

<cfcookie name="CFID" value="#CFID#">
<cfcookie name="CFToken" value="#CFToken#">

This will cause cookies to be set in the browser for this second server, tying their session there.

In the couple times I’ve needed to do this the applications were using Application.cfm files, not Application.cfc. I’m guessing the only consideration when doing this with Application.cfc would be - where would the cfcookie tags go? I’m guessing in OnRequestStart().

3GB of memory for ColdFusion on Linux

Saturday, March 8th, 2008

There has been some discussion on various ColdFusion discussion lists regarding the maximum heap size you can allocate to ColdFusion/Jrun. Windows allows a process to grab as much as 2GB of contiguous memory. Subtracting out memory for overhead, permgen memory, etc. you are left somewhere with 1.5-1.8GB available for general heap memory.

We were considering moving one of our clients to a Linux server if that would allow us to allocate more memory to the heap. In my research, it seemed the opinions were split about 50/50 as to if Linux would allow us to allocate more than 2GB of memory. So I decided to test for myself. I placed an order for 4GB of memory and waited for them to arrive.

Once I had swapped out my 4 256MB modules for the 4 1GB modules, I increased the heap size (Xms and Xmx options in jvm.config) to 2048 and restarted the server. No problems! I kept increasing by 100mb at a time until I reached 2600 - there it failed to start, so I backed it down to 2500mb. With the permgen and other overhead, Jrun was taking up about 2950Mb of memory - indicating a 3GB limit. I have been running this way for a few days now with no problems.

Your experience may vary of course, depending on what memory options you have in your jvm.config file. I did not need to do anything special other than bump up the Xms and Xmx values.

So the short answer is Yes, you can allocate about 1GB more memory to ColdFusion when running on Linux.

Getting cfstat to work

Tuesday, March 4th, 2008

The command line statistics program supplied with ColdFusion, cfstat, has never worked for me. I’ve never tried it on Windows, but I have tried it on Linux on versions 6 and 7, and now version 8.

A little digging around told me why it never worked in CFMX 6-7. Apparently the cfstat script was looking for a particular jar file using a relative path - so it only worked if you were calling it from within the ColdFusion installation directory, which I guess I never did. Looking at the cfstat script in version 8, I can see they specify the full path.

But cfstat still wasn’t working for me in CF8, I got this error message:
(more…)

Rotating PDFs in ColdFusion

Sunday, February 24th, 2008

On a recent project I needed to be able to rotate PDF documents. I thought for sure there would be something like <cfpdf action="rotate">, but I was surprised there was no such option. I came across ColdFusion 8’s built in DDX processing feature, and thought I would just do it with that. Turns out the limited DDX engine in ColdFusion does not include the ability to rotate.

But there is a way! The iText class libraries are bundled with ColdFusion, and they are capable of turning your PDFs on end.
(more…)

Getting the size of a file in ColdFusion

Wednesday, February 13th, 2008

Today I needed to get the size of a file I’m working with. If the file was being uploaded from an html form, I can get the file size after calling <cffile action="upload"> by looking to the cffile.fileSize variable. But in this case, my file was uploaded long ago.

It is possible to get the file size by using <cfdirectory action="list" directory="parentDir">. This will return a query containing entries for each file in the directory. One of the columns in the query will be the file size. You can narrow it down to returning only your file by specifying a filter.

<cfdirectory action="list" directory="parentDir" filter="myfile.txt">

I don’t know if this filter is applied before or after the directory contents are read in. Anyway I didn’t really like this approach, maybe I’m just spoiled by Ruby’s simplicity ( File.size(”myfile.txt”) ), but this seems like the round about way to get a file’s size.

There is a more elegant way to do it with Java, and its very simple. If we create a Java “file” object, we can call the length() method on that object to get the size of the file in bytes. You can do it in one line.
(more…)

You *can* set Java system properties via ColdFusion

Monday, February 11th, 2008

I was recently working with some java libraries that looked to a system property for a configuration setting. The sample Java app that came with the library was setting the system property on the command line. Their windows .bat file and Linux shell script both launched the java app like this:

java.exe -cp .;package1.jar -Dcom.company.product.maxvalue=500 SampleApp

Note tha -D option, that sets the java system property com.company.product.maxvalue to 500. If you are not familiar with java system properties - they are kind of like a global variable, accessible via any java code.

I didn’t want to have to edit my Jrun start up options and add the -D option on there. That option is not even possible for many ColdFusion users. But setting a system property via ColdFusion is actually very easy.
(more…)

ColdFusion 8 auto-suggest shows through other form fields

Wednesday, January 30th, 2008

I was creating a form the other day that had 3 form fields, layed out vertically on top of one another. I switched the first field to be a cfinput, so I could use the autosuggest feature:

cfinput example 1
(more…)

ColdFusion 8 inline array syntax doesn’t work everywhere

Friday, December 21st, 2007

I was trying to use QueryAddColumn() today to add an additional column to a single-row array I’m working with. The 4th parameter to QueryAddColumn is an array of values to add to the query - 1 element in the array for each row in the query. Since my query only has on row in it, I thought this would be a good place to use ColdFusion 8’s new inline array syntax.

<cfset QueryAddColumn(qryFoo,
                     "newColName",
                     "varchar",
                     ["my additional value"])>

But this throws an unhelpful “Missing argument name” error:

Missing argument name. When using named parameters to a function, every parameter must have a name.

It took me a while to figure out it just didn’t like using the new array syntax inside the function. Doing it this way worked fine:

<cfset myArray = ["my additional value"]>
<cfset QueryAddColumn(qryFoo,"newColName","varchar",myArray)>

But having to do it that way kind of defeats the point, it doesn’t use any less lines than the old CF7 syntax:

<cfset myArray[0] = "my additional value">
<cfset QueryAddColumn(qryFoo,"newColName","varchar",myArray)>

And it means I have to “var” the myArray variable at the top of my function now. Hopefully Adobe will get this straightened out at some point.

CFC for generating and reading 2D barcodes in ColdFusion

Saturday, December 15th, 2007

One of the projects I’ve been working on recently requires the ability to receive faxes and place them into a customer’s account. At first we looked at using optical character recognition to scan out the customer’s ID from the cover sheet, but this route was looking expensive and time consuming, and we weren’t sure we would be able to reliably read the customer IDs, since faxes are sometimes hard to read even with the human eye. We are providing a pre-filled out cover sheet, so the customer ID would be printed, not hand written, but I think it would still be difficult to read.

Just around this time I saw Jim Rising’s post on cf-talk saying that if you need to do this kind of thing, you really should be looking at using a 2D barcode instead of trying to OCR a number. So I did. He mentioned Java4Less, a company that sells reasonably priced (~$100) java libraries for reading and writing barcodes, including data matrix barcodes. A datamatrix barcode is a 2D barcode that can encode more data in less space than a traditional barcode. Its also much more durable, and can be read even when faxed several times. They look like this:

datamatrix barcode example

(more…)

Rounding values in a Query of a Query

Wednesday, October 24th, 2007

I encountered a problem (or should I say an “opportunity”) where I needed to do some rounding in a query-of-a-query. This is normally very easy to do in most RDBMS, as there is usually some type of Round() function you can use. In my case I needed to round a percentage I was calculating in the Q of a Q down to only 1 decimal place. And I didn’t even really need to round it - I would be ok with simply truncating. Turns out this is a little difficult to do in a query of a query. There are no round() functions, no ceiling() or floor(), and no string manipulation functions. Here is what I came up with:
(more…)