Friday, May 9, 2014

Quick ColdFusion WebSockets Gotcha

I've been playing around with CF WebSockets for a few days now and have just started to work on message filtering.  Through the use of a selector I can target messages to a single client (or range of clients).  This is great, as there was a bug in the implementation of Flash Remoting and ColdFusion that broke filtering.  This meant that I had to send messages to all connected clients and filter on the client side, which as you can imagine is noisy.

Here is the Javascript I am using to subscribe and publish where ws is the ColdFusion WebSocket object created with the cfwebsocket tag:
ws.subscribe("messaging.friends", {userid: $('#userid').val(), selector: "targetuser eq '"+userselector+"'"}, friendsCallback);

...

ws.publish("messaging.friends", $("#message").val(), {targetuser: $('#userid').val()});
The simple code above subscribes to the messaging.friends subchannel using a selector that jQuery grabs from a web form.  The second line of code published a message to that channel with the same targetuser to match the selection criteria.

When I tested filtering I found that all of my messages were being delivered regardless of filtering criteria.  I had read previously that if your channel listener CFC implemented the canSendMessage() method, that this would occur.  I had removed the offending function but all of my messages continued to arrive regardless of selector criteria.

After much frustration I restarted ColdFusion and everything started working.  What seems to have happened is that when CF the Java creates classes from your CFC it picks up on changes within a method, but does not pick up that a method has been removed until the server is restarted (or if the application ends would be my guess).  Hope this saves someone some time.

Friday, January 4, 2013

BlazeDS Error with an Illogical Fix

I've been having nothing but problems with BlazeDS lately, and I wanted to share an oddity I came across.

Configuration errors are the bane of my existence.  I don't want to know how BlazeDS works under the covers, it always just works.  That's why I use it, plus it's integration with Adobe ColdFusion and Grails (if you use the BlazeDS plugin).

For the past few days I have been receiving the error:
[BlazeDS]Exception occurred during serialization: java.lang.NullPointerException
NPE errors are always so helpful.  The basic setup is that CF sends an Apache Flex client messages.  Message1 occurs when a user signs in.  I notify the CF server via a RemoteObject call, and it then pushes a message out to all connected clients using BlazeDS the ColdFusionGateway channel.  This is working great and the Flex client receives the message via a consumer subscribed to an AMF polling channel.

The message in question occurs when a new person joins a group chat.  I send a DTO to CF via the sameRemoteObject, and then the CF sends a message to all clients that care about this specific group chat.  This fails with the above error when the client polls for its messages.  I am however, able to send the message from a browser test file through the same gateway and Flex receives the message and everyone is happy.

If I make the same call from Flex and disregard the DTO sent from Flex, creating my own DTO on the server side, I also get the error above.

What is weird is the first case works, and the second case does not.  The fix was to go into the config file that ColdFusion uses in its gateway config {cfroot}/WEB-INF/cfusion/gateway/config/flex-messaging-gateway.cfg and comment out the line "host=localhost".

The config file states:
# [Optional] The hostname or IP address of the Flex server.
# If omitted, the Flex server is expected to be installed as part
# of ColdFusion.  Specify 'localhost' if Flex is on this machine but
# not installed as part of ColdFusion.
I don't know what it means to install Flex as "part of ColdFusion" but the Flex client is running from the debugger, so it is definitely not part of ColdFusion.  I don;t think there has been a Flex Server component since version 1.5.  If they mean BlazeDS or Flash Remoting, then, maybe?  Either way, the configuration help needs improved upon.

While I can't explain what is going on here, I can at least provide the above solution so that someone else can save the 4 days it took me to figure this out.  Enjoy!

Thursday, January 3, 2013

ColdFusion 9 and ColdFusion 10 Together - Behind Apache HTTP Server

I have several projects using Adobe ColdFusion 9 and a new one starting on CF 10, so I needed to get CF 10 (running on Apache Tomcat of course) behind an Apache HTTP server.  I was having some issues finding anything via Google, but hidden behind a dead page that I could view only in text-mode via the cache was this gem from one of Adobe's ColdFusion engineers, Kavya: Co-existence of ColdFusion9 and ColdFusion10 using Apache web server

I was running a beta version of ColdFusion 10 so I had some issues initially, where the CF 10 instance ignoring the DocumentRoot directive and pushing me into the {cfwebroot}/cfusion/wwwroot directory.  One I reinstalled the latest release all was fine.

Two notes from Kavya's post:
  1. If you are not familiar with Apache HTTP server and are setting it up on multiple ports, you'll need to add Listen directives inside your httpd.conf file (e.g. Listen 81), one port per line.
  2. I set mine up all listening on port 80 and it worked beautifully.  Not sure if anyone still needs the workaround with multiple ports.
 Hope this cross-post will help Kavya's post get some traffic, as I couldn't find it on Google.

Monday, December 31, 2012

BlazeDS Error Solved

I have been working on a fun project that requires a streaming gateway between Adobe ColdFusion and Apache Flex.  I had a vanilla installation of CF 9.0.2 (after numerous attempts to configure my current setup) and was consistently getting the error:
Unable to find the Flex adapter for destination ColdFusionGateway in the RMI registry on localhost:1099
I haven't done much Java in some time and BlazeDS installed with CF 9 is generally pretty simple, so I correctly assumed the problem was configuration related instead of going down a rabbit hole.  The problem was that this code was working on another of my machines just fine, and this is a fresh install and the config files matched.

Googling brought up the same few posts which were not related to my situation, so I wanted to post the solution here quickly in case I can save someone else 3 days of hair-pulling.

In the end I had to change the definition for the ColdFusionGateway destination in messaging-config.xml.  I had to uncomment and set the gatewayhost property to localhost as shown below:
<gatewayhost>localhost</gatewayhost>
The help text states:
If ColdFusion is running on a different host, enter that here.  Default is to expect ColdFusion and Flex to share the same web application. You must enter 'localhost' if CF and Flex are not in the same web app.
This doesn't make sense since I am calling the messaging component from within ColdFusion (BlazeDS installs with CF 9+).  This is why I couldn't figure out what setting needed flipped.  I would understand if I was getting this message in my Flex application, as in my current test environment the Flex application I am working on I am running out of Flash Builder in debug mode.  The Flex project does not live anywhere within the context of ColdFusion so this setting would make sense.

I also don't recall ever having to do this prior to ColdFusion 9.0.2.  It is also worth noting that I am on Mac OS X Mountain Lion (10.8) and also reproduced this in 9.0.2 on OS X 10.7.

Regardless, I am back up and running, and if you are reading this I hope this helps you as well.

Tuesday, July 17, 2012

Quick IntelliJ Tip - Disable Unlimited Whitespace

It drives me nuts when my code has trailing spaces at the end of a line when programming.  Why anyone would want this is beyond me.  I'm a Mac and running IntelliJ 11.1 Ultimate.  To disable this wonky feature I had to do some digging.

What you need to do is go to your IntelliJ IDEA menu and click 'Preferences'.  Select 'Editor' from the preferences panel (under IDE Settings) and in the upper right you will see a heading for 'Virtual Space'.  Uncheck 'Allow placement of caret after end of line'.  Not sure why it is named caret instead of cursor, but who cares.  I can now cmd-arrow to the front and back of the line as with Eclipse.

Wednesday, May 16, 2012

Need ColdFusion 9 with Verity? Go Get it NOW!

Rakshith, the dashingly handsome newlywed ColdFusion Product Manager just posted this on the ColdFusion Blog:
"Our contract with Verity will soon end and we will no longer be able to allow downloads that have Verity in it (CF9/CF8 installers have Verity) post 31st of May."
This means, and I can't stress it enough, that if you rely on Verity you need to go grab the 9.0.1 installer right now.  The ColdFusion Team will be releasing ColdFusion 9.0.2 on June 1 and purging all pages of 9.0.1 downloads.  9.0.2 will not contain the Verity engine, and only Solr will be an option for searching.

Saturday, March 10, 2012

Some Nifty Adobe ColdFusion 10 Language Changes

I am reviewing the Adobe ColdFusion 10 beta documentation and wanted to point out a few small things I was happy to see.  These might not be earth shattering to you, but these will affect the way I write code so I felt it was worth sharing.

Thing 1: for - in syntax for looping queries
ColdFusion 10 (codenamed Zeus) allows us to loop over queries in cfscript using for - in syntax.  This syntax was previously used for looping keys in a structure.  I had previously mentioned this in my post Dear ColdFusion Team: Please fix this stuff in Zeus as number 4.  Maybe someone read my blog, or maybe it just made that much sense ;)

The new syntax looks like this:
for ( row in myQuery ) {
  fullname = row.fName & row.lName;
}

How does this affect my code?
It makes life so much easier and code so much more elegant (as ColdFusion is meant to be), especially when you consider the code we write in ColdFusion 9:
for ( var x=1;x<=myQuery.recordCount;x=x+1 ) {
  fullname = myQuery.fName[x] & myQuery.lName[x];
}

It also feels more like the tag based alternative, which I generally think is a good thing.

Thing 2: Retrieve Application Metadata
ColdFusion 10 adds a new function called getApplicationMetadata().  This is pretty cool as when you dump out the application scope you generally only see application variables, with the exception of the application name.  The new getApplicationMetadata() function provides insight into the application settings themselves.

getApplicationMetadata() output


How does this affect my code?
I can see several uses for this, but the first one that immediately jumps to mind is that I can sync us my JavaScript timeouts with my session timeouts.  That alone is pretty big to me, since I write HTML/Ajax apps.  This helps with pingback and timeout redirection.  Some of this I can also see being really helpful for framework and 3rd party app developers.

Thing 3: onAbort Application method
Although I now have to change my ColdFusion Application.cfc presentations to stop saying 7 application events ;), I'm happy that this function has been added.  What it does is allows you to process the results when you use <cfabort> or abort;.  The new application event handler is placed in your Application.cfc file.  Here is the syntax, directly from the documentation:
<cffunction name="onAbort"
access="public"
returntype="void"
hint="Hanldes Aborted request">
<cfargument type="String"
name="targetPage"
required=true/>
<cfoutput> Target Page: #targetPage#</cfoutput>
<!--- do stuff --->
</cffunction>
}

How will this affect my code?
To be honest, I haven't decided yet.  I imagine I will be able to start using <cfabort> for more than just debugging, but it hasn't quite solidified in my mind yet.

Thing 4: Ability to slice arrays
I don't need to go too in depth on this one.  It's something that I can do in other languages and is an important part of array handling.  Here is the syntax, right from the docs:
<cfscript>
array = [1, 2, 3, 4, 5, 6, 7, 8];
newArray = arraySlice(array, 2, 3);//returns 2,3,4
newArray = arraySlice(array, 4);//returns 4,5,6, 7, 8
newArray = arraySlice(array, -5, 3);//returns 4,5,6
</cfscript>

How will this affect my code?
Easy, I won't have to finagle my arrays.  We now have a language construct to slice.

Thing 5: Method chaining in CFCs
Since ColdFusion 6 we have been able to method chain to a certain degree.  This worked across multiple CFCs (following the object's composition):
employeeName = company.getEmployee().getFullname();

This should not be confused with the new method chaining within beans, which specifically affects mutator methods in our objects (if we have accessors explicitly defined of accessors="true" in our CFC definition).  Check this out:
employee.setName('Bob').setDepartment('Accounting').setFavoriteColor('Green');

How will this affect my code?
The jury is still out on this one for me.  I use method chaining like this in jQuery often.  I personally think it makes my code more legible.  It is certainly shorter code, but is it really better?  Not sure.

Thing 6: Structures now support colon notation
#1 on my Dear ColdFusion Team: Please fix this stuff in Zeus list, I am certainly happy to see this.  Railo already did this, as did other ECMAScript based languages such as JavaScript and ActionScript.
st = {
  name: 'Richard',
  age: 44,
  favoriteColor: 'Purple'
}

Again CF team, thanks for listening!

How will this affect my code?
Easy. I won't have to troubleshoot stupid errors when I move from language to language any more.  I can always use the same accepted syntax!

Other stuff
There are plenty of other language changes in ColdFusion 10.  Just because I don't use them doesn't mean they aren't great.  I encourage you to comment on some that will change the way you code.  I bet the directoryCopy() function and <cffile> improvements alone have people thinking in new ways.  Oh, and closures.