Line Debugging Causes CF to Not Start

So you go to turn on line debugging in ColdFusion, and when you save your changes, it warns you that the ColdFusion service will fail to start if the debugging port is already in use. Great, but what do you do if this actually happens?

I was at a loss for a few minutes on how to get ColdFusion started again so that I could fix the issue. Well, the configuration change is in your ColdFusion installation under ~/runtime/bin/jvm.config. So on a typical Windows installation, it may be c:\coldfusion9\runtime\bin\jvm.config.

Note: Before proceeding, it is always good practice to make a copy of the config file before editing it.

In jvm.config, there is an “Arguments to VM” section that has a java.args setting that may start with something like this:

java.args=-Xdebug -Xrunjdwp:transport=dt_socket, server=y, suspend=n, address=5095 -server -Xmx512m

(There will likely be many more arguments as well.)

The first two arguments contain the debugging settings that are probably preventing ColdFusion from starting. Remove the -Xdebug and
-Xrunjdwp:transport arguments, so that the beginning of the line will now look like this:

java.args=-server -Xmx512m (and additional arguments…)

This will be enough to get ColdFusion to start up. You can then go into ColdFusion Administrator to either change the debugging port or turn off the line debugging.

Reset Access Datasources Without Resetting ColdFusion

I am “stuck” with a few web applications that provide web front-ends to Access databases. I am not the owner of these databases, and for various reasons, the database owner will not upgrade it to SQL Server. Alas, this sometimes causes headaches like the following.

The Access databases are on a network fileserver. Occasionally, this server goes down or resets, and ColdFusion’s datasource connection to the database gets stuck in a disrupted state. I’ve come to learn two things you can try to get ColdFusion’s connection to the Access datasource working again without resetting the entire ColdFusion Application Server service, which is obviously disruptive to your entire site and all of its applications.

  1. Reset the ODBC services. The ColdFusion ODBC services (such as “ColdFusion 8 ODBC Agent” and “ColdFusion 8 ODBC Server”) actually handle the ODBC connections to DataDirect driver databases such as Microsoft Access databases. This is handy. Just reset these services and often connectivity is restored.
  2. Use the “Disable Connections” option in the datasource configuration. If you are using JDBC drivers (for instance, perhaps to connect to Microsoft Access 2007 databases), resetting the ColdFusion 8 ODBC Server service won’t help. Darn. However, if you go into the datasource’s configuration in ColdFusion Administrator, you can check the “Disable Connections” checkbox and submit the change. This will force ColdFusion to disconnect from the database. Immediately go back in and uncheck the checkbox and submit again. Your datasource will now have connectivity reestablished without a ColdFusion restart!

Happy days! The second option won’t be helpful to you if you have many, many datasources. However, this is better than a ColdFusion reset that would disrupt all of your apps.

Generating a Decrypted Memento for a Transfer Decorator

In my last blog post, I discussed how to efficiently handle multiple encrypted fields while using Transfer. The key was using onMissingMethod in the Transfer decorator. However, what about when we use the memento with Transfer's getMemento() method? This approach can be especially handy to quickly transfer an object's properties when using web services to Flex or AJAX front ends.

For reference, here was the object definition we were using in our sample Transfer configuration.

XML:
  1. <object name="Reg" table="Regs" decorator="MyProj.com.Reg">
  2.   <id name="ID" column="RegID" type="numeric" />
  3.   <property name="FName" type="string" column="RegFName" />
  4.   <property name="LName" type="string" column="RegLName" />
  5.   <property name="LastMod" type="date" column="RegLastMod" />
  6.   <property name="Expires" type="date" column="RegExpires" nullable="true" />
  7.   <property name="EncHome" type="string" column="regHome" />
  8.   <property name="EncWork" type="string" column="regWork" />
  9.   <property name="EncMobile" type="string" column="regMobile" />
  10.   <property name="EncSMS" type="string" column="regSMS" />
  11. </object>

The process is very simple. Recall that we prefixed our Transfer properties with "Enc" to know which fields are encrypted. Let's create a getDecryptedMemento() method. It will loop through all of the keys in the memento, which is just a struct, and decrypt any of the encrypted fields, saving them as new keys in the struct (i.e. "EncHome" is decrypted as "Home" in the struct).

Something like this will do the trick:

CFM:
  1. <cffunction name="getDecryptedMemento" access="public" returntype="struct" output="false">
  2.   <cfset var memento=getMemento()>
  3.   <cfset var key="">
  4.   <cfset var newkey="">
  5.   <cfloop index="key" list="#StructKeyList(memento)#">
  6.     <cfif Left(key,3) is "Enc">
  7.       <cfset newkey=RemoveChars(key,1,3)>
  8.       <cfset memento[newkey]=decryptValue(memento[key])>
  9.     </cfif>
  10.   </cfloop>
  11.   <cfreturn memento>
  12. </cffunction>

Not much to it. Note that we would use the same decryption function as we are using in onMissingMethod for the dynamic accessors. I'm calling it decryptValue() for this sample.

In the end, our getDecryptedMemento() method returns a memento that looks just like the Transfer-generated getMemento() output, with decrypted versions of the encrypted fields!

Handling Multiple Encrypted Fields in a Transfer Decorator

I had a recent project that had multiple fields in a particular table that needed to be encrypted for privacy and security considerations. I was using Transfer for the project. The typical way to handle the encryption is to create custom accessor methods in a decorator component. The Transfer wiki has a decent explanation of this concept on a page entitled How to Encrypt User Passwords Using a Decorator. However, it is intentionally simple, demonstrating a single property. Multiply your getter/setter methods by how many properties you will be working with, and the lines of code can add up. This framework stuff is supposed to prevent that kind of repetition! Well, utilizing onMissingMethod() and the core concept on the Transfer decorator example, we can handle this scenario efficiently.

First, let's consider the object definition in our sample Transfer configuration file.

XML:
  1. <object name="Reg" table="Regs" decorator="MyProj.com.Reg">
  2.   <id name="ID" column="RegID" type="numeric" />
  3.   <property name="FName" type="string" column="RegFName" />
  4.   <property name="LName" type="string" column="RegLName" />
  5.   <property name="LastMod" type="date" column="RegLastMod" />
  6.   <property name="Expires" type="date" column="RegExpires" nullable="true" />
  7.   <property name="EncHome" type="string" column="regHome" />
  8.   <property name="EncWork" type="string" column="regWork" />
  9.   <property name="EncMobile" type="string" column="regMobile" />
  10.   <property name="EncSMS" type="string" column="regSMS" />
  11. </object>

Note that I have prefixed the Transfer properties with "Enc". This isn't required, but will simplify our processing later on. So in this sample, we have 4 properties: Home, Work, Mobile, and SMS. The concept is that these are client phone numbers that we want to protect with encryption. So, Transfer will generate getEncHome(), getEncWork(), getEncMobile(), getEncSMS(), and corresponding setters. However, we want to provide getHome(), getWork(), getMobile(), getSMS(), and corresponding setters, that get and set the properties after encryption/decryption.

Use onMissingMethod()

To accomplish this, we might have an onMissingMethod() function in the decorator like this:

CFM:
  1. <cffunction name="onMissingMethod" access="public" returntype="any" output="false">
  2.   <cfargument name="missingMethodName" type="string" required="true">
  3.   <cfargument name="missingMethodArguments" type="struct" required="true">
  4.   <cfscript>
  5.     var func="";
  6.     var encList="Home,Mobile,SMS,Work";
  7.     var method=Arguments.missingMethodName;
  8.     var args=Arguments.missingMethodArguments;
  9.     var firstArg=args[ListFirst(StructKeyList(args))];
  10.     var prop=RemoveChars(method,1,3);
  11.     // Handle encryption/decryption of encrypted values:
  12.     if( ListFindNoCase("get,set",Left(method,3)) and
  13.         ListFindNoCase(encList,prop) )
  14.     {
  15.       func=variables[Insert("Enc",method,3)];
  16.       if( Left(method,3) is "get")
  17.         return decryptValue(func());
  18.       else
  19.         func(encryptValue(firstArg));
  20.     }
  21.   </cfscript>
  22. </cffunction>

As a good security measure, we use an "encList" string to check that only proper methods can be called. Then we examine the method name. If it starts with "get" or "set" and ends with one of the list items, we proceed. Thus, we'll process a method like getHome(), but not a method like getFoo(). We then call getEncHome() and decrypt it for getters, encrypt and call setEncHome() for setters.

Dynamic Method Calling

But alas, how do we do this dynamically without a long if-then-else chain? We call the proper method by referencing it from the component's variables scope. Terrence Ryan describes this in his blog post Cheap and Easy Dynamic Method Calling in CFScript. We construct the method name, in our case, by inserting "Enc" after the "get" or "set" prefix of the method name passed into onMissingMethod (thus "getHome" becomes the Transfer method "getEncHome"). Assign the function to the local "func" variable, then call it as if "func" was the function. Finally, handle any encryption or decryption that you will be doing. For this sample, I have encryptValue() and decryptValue() methods handling the details of that work.

Summary

We've used two solutions to handle multiple encrypted fields in the decorator. First, we used onMissingMethod() to handle processing of all of the properties in a single method. Then, we used dynamic method calling to call the Transfer-generated accessors within onMissingMethod().

The end result is being able to use setHome(), getHome(), etc. with the encryption and decryption being handled automatically. Great!

In addition to accessors, we may sometimes want to use the object's memento with the Transfer method getMemento(). In my next blog post, I'll demonstrate how that process can also be done very efficiently.

  Theme Brought to you by Directory Journal and Elegant Directory.