The strangest CF error ever: IP_ADD_MEMBERSHIP failed (out of hardware filters?)

So today I tried to cfdump something to see what was available for methods and data, but when I'd run the code with the cfdump in place, I would get:

view plain print about
1IP_ADD_MEMBERSHIP failed (out of hardware filters?)
2net.sf.ehcache.CacheException: IP_ADD_MEMBERSHIP failed (out of hardware filters?)
3at
4net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:93)
5at net.sf.ehcache.CacheManager.init(CacheManager.java:241)
6at net.sf.ehcache.CacheManager.(CacheManager.java:221)

Remove the cfdump, things worked fine. Add it back in, get the error. I restarted the server, no good. So I googled. And I found something!! Google knows all, Google sees all.

Strangest freaking error message and behavior evar!

But, thanks to Microsoft via Brian Kotek through Ray Camden, I got the right idea... but the technote was for the wrong version of windows. Back to Google, Sauron's Eye of the Interwebs, and behold, an answer on Microsoft Answers.

Once you've issued the command-line bits you'll need to restart your J2EE server... but boom... it all worked!

And for those hearty souls that like the nitty-gritty, here's the dope on this issue.

UPDATE: OK, so it turns out I should have read the comments on Ray's blog entry, because the link status detect didn't fix the issue. Turns out it's a result of EHCache trying to use multicast (yes, that'd be UDP) over VPN... apparently notoriously unsupported but breaks CF's default EHCache settings. So, the solution is fairly simple, really...

Edit {jrun_home}/servers/{server_name}/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/ehcache.xml and remark out the following two lines:

view plain print about
1<cacheManagerPeerProviderFactory
2 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
3 properties="peerDiscovery=automatic,
4 multicastGroupAddress=230.0.0.1,
5 multicastGroupPort=4446, timeToLive=1"

6 propertySeparator=","
7/>

8<cacheManagerPeerListenerFactory
9 class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

Make those changes (the lines come after descriptive comments, I just moved the comment closer down 2 lines), restart your J2EE instance and you're golden!

Either that or spend your workday in isolation, dropped off VPN! lol

Excellent explanation of heap/non-heap I've seen

So this morning while I waited for a Subversion update to complete (large repos across VPN suck by the way), I was cruising the JavaDocs for the javax and java.lang packages. Why? Cuz I'm a geek... dude, that should be obvious. HELLO!

Anyway, I was clicking here and clicking there and finding things generally interesting... when I suddenly found myself reading the description of a class very thoroughly. Why? Because (as the title may have betrayed) it was the one of the more enlightening, most concise explanation of heap space, non-heap space and garbage collection I've read... to date. And I've been at this for a while now.

Ironic, to find something like that hidden in the JavaDocs for java.lang.MemoryMXBean of all places.

Here's the link. Give it a read and let me know what you think...

Laterz!

ColdFusion 9: cfscript DOES support rethrow!

In a conversation that came up during a meeting today, there was some discussion as to whether or not ColdFusion 9's beefed-up CF Script support included rethrow. Next thing you know a few of us dash off to test it.

Turns out it supports it as a statement. Also turns out that it's not mentioned in the ColdFusion 9 documentation, at least not in the sections that act as documentation for CF Script. Sadly, the whole CF Script section of the Developer's Guide kinda sucks and in the language reference (actually referred to as the CFML Language Reference) it's not mentioned outside the tag, and that just has a link to the Developer's Guide.

Blog time! So...

It works. And I also discovered a way of using it that I'd never thought of before. If you have a catch statement that does some things like logging or an alternate behavior or something, but then you want to return the flow to the built-in error handlers, you can do it like this:

view plain print about
1<cfscript>
2    try {
3        if (a==1) b=2;
4    } catch (any a) {
5        writeDump(var=a);
6        rethrow;
7    }
8
</cfscript>

I've only ever used it in CFCs where I was going to have deep composition and I wanted to be sure that a particular error was going to be the one that was seen. It changes where the error gets reported from, locally where the code is executing or from the caller's perspective. Without rethrow, the error will usually be reported from the caller's perspective instead local to the running code.

Happy throwing...

Laterz!

Output buffer, anyone??

Alright, now for the last and final debunking of the PHP vs ColdFusion - a test against time" post by our dear PHP apologist friend Mr. Phil Parsons. I'm sure by now he's deliriously happy he bothered to post that article in the first place. One thing you have to say for ColdFusion: the fans are fierce, loyal and knowledgeable. Challenge us only if you have your ducks in a row and your thinking cap on tight. And I'm sure if I try I can mix a few more metaphors before I finally sleep tonight.

Or we could just skip to the code...

So. I started out working with 200,000 characters. I mean, what fun is it if we can't outdo PHP at its own game, eh? I managed to roll 200,000 characters from local variable into a page buffer and into a different variable in .36ms. I have NO freaking clue why this particular test is significant, but apparently it's one of the ways in which PHP is purportedly better than ColdFusion. However, I just realized something:

Mr. Parsons is running a comparable CPU to mine, however he's running it overclocked at more than 1GHz faster than my lowly (and 4-year-old) MacBook Pro. Intel Core2 Duo 2.8 GHz LAPTOP vs AMD Phenom II X2 550 3.10 GHz @ 3.83 GHz DESKTOP. I wonder how my tests would run on a DESKTOP machine running a full GHz faster than my laptop? Especially considering that in general desktops GHz for GHz perform a bit better than laptops anyway?

So I dropped my character count to 140k, just like his and guess what? My poor, humble laptop burdened with running ColdFusion in a J2EE container, PHP5, Apache, Eclipse, FireFox, and about a half-dozen other things (I currently have 24MB of RAM free, yes, 24MB) managed to run his same test in .26ms. That's .06ms slower, on hardware running a full GHz slower. So you tell me which performs better.

Really... next time you decide to take on another platform with trickery and deceit, Mr. Parsons, think twice.

And now, finally, here's the code!

view plain print about
1<cfscript>
2    string = fileRead(expandPath('.') & "/resources/140kchars.txt");
3    its = 10000;
4    times = [];
5    writeOutput("Char count in the string: " & len(string) & "<br />");
6
</cfscript>
7
8<cfloop from="1" to="#its#" index="i">
9    <cfset start = getTickCount()>
10    <cfsavecontent variable="string2"><cfoutput>#string#</cfoutput></cfsavecontent>
11    <cfset end = getTickCount()>
12    <cfset arrayAppend(times,end-start)>
13</cfloop>
14<cfscript>
15    writeOutput("Char count in the new string: " & len(string2) & "<br />");
16    writeOutput("It took an average of " & arrayAvg(times) & " miliseconds to do whatever it was we just did " & its & " times.");
17
</cfscript>

Interestingly, the bigger the value in the its variable (the number of times we repeat the experiment) the FASTER OUR AVERAGE TIME IS. I just find that extremely interesting. God bless HotSpot. :)

Laterz!

OK, so let's talk object creation...

I'm making sort of a series out of poking holes in the anti-ColdFusion ramblings of an admittedly biased blogger. Pro-PHP blogger Phil Parsons blogged about how ColdFusion is tragically slower than PHP and is therefore something we should all stay away from if performance is any kind of concern. Unless we want to connect to MS Exchange... maybe.

So his second example was object instantiation performance. Arguably, one of ColdFusion's weak points... but not something entirely unworkable. People who complain about this generally only do so because they don't know how to best use CFC's and, most especially, how to write them properly. Nowhere is this more apparent than in Mr. Parsons' components. If this is how he writes CFCs it's no wonder his employer has "to constantly make decisions NOT to use OO features of Coldfusion based on [sic] it's poor performance." (That quote is from his comments below the article).

You can download the source he uses in the article, so I'm not going to post that here. I will say that the primary critiques I have against them are things like the ungodly amount of white space, the silly variable creation in the pseudo-constructor and the amazing number of unnecessary expressions.

What I am going to show you is my version, and then I'll share my results.

Colony.cfc

view plain print about
1<cfcomponent displayName="Colony" output="false">
2
3    <cffunction name="init" output="false" returntype="Colony">
4        <cfargument name="cn" type="String" default="colony">
5        <cfscript>
6            colonyName = arguments.cn;
7            drones = arrayNew(1);
8        
</cfscript>
9        <cfreturn this>
10    </cffunction>
11    
12    <cffunction name="addDrone" output="false" returntype="void">
13        <cfargument name="drone" type="Drone" required="true">
14        <cfset arrayAppend(drones, drone)>
15    </cffunction>
16    
17    <cffunction name="getDroneCount" output="false" returntype="numeric">
18        <cfreturn arrayLen(drones)>
19    </cffunction>
20
21</cfcomponent>

Drone.cfc:

view plain print about
1<cfcomponent displayname="Drone" output="false">
2    
3    <cffunction name="init" output="false" returntype="Drone">
4        <cfargument name="m" type="String" required="true" default="">
5        <cfset message = m>
6 <cfreturn this>
7 </cffunction>
8    
9    <cffunction name="getMessage" output="false" returntype="String">
10 <cfreturn message>
11 </cffunction>
12    
13    <cffunction name="setMessage" output="false" returntype="void">
14        <cfargument name="val" type="String" required="true">
15 <cfset message = val>
16 </cffunction>
17
18</cfcomponent>

colony.cfm:

view plain print about
1<cfscript>
2    Colony = new objects.Colony("colony1");
3    
4    start = getTickCount();
5    while (Colony.getDroneCount()
< 10000) {
6        Colony.addDrone(new objects.Drone());
7    }
8    end = getTickCount();
9    writeOutput("Adding 10,000 Drones to the Colony took " & end-start & " miliseconds.");
10</cfscript>

And now for the really bad news:

While I managed to blow his unquestionably inflated time of roughly 600ms or more right out of the water, ColdFusion continues to have a weak spot around object instantiation. The best I could do was slightly less than half of what Mr. Parsons got. I manged to get this test down to 250-300ms. Still substantially slower than the 42ms he reported for PHP. So while Mr. Parsons was grossly exaggerating the problem, the problem yet persists. Even with the drastic improvements the ColdFusion team managed to pack into ColdFusion 9.0.1 over previous versions.

The question you have to ask yourself, at that point, is whether it really makes any difference. CFCs (and OO in general, really) are about maintenance, and there are ways you should use them and ways you shouldn't. Not knowing those rules, or worse knowing them and deliberately refusing to use them, and then presenting yourself as someone with something worthwhile to say on the subject is just plain dishonest. It's been years since I've worked on an application that was written without CFCs, and even the ones that were poorly done performed adequately. The ones that were written with CFC best practices in mind were actually extremely performant.

In other words, there's no reason for anyone's employer to refuse to use them due to performance or any other reasons but ignorance, poor design and (worst of all) hyperbole. It's no different than knowing you should be using arrays instead of lists, or that structures are passed by reference and arrays by value. Go ahead, it's OK. Use CFCs in your applications... just do it intelligently, keeping in mind what works and (most important) what doesn't. And use ColdFusion's built-in data structures to their maximum advantage: structures, queries, arrays, oh my! Use the scopes, too: server (far too often overlooked), application, session, request, variables, this, super, caller, etc. The list goes on and on.

Programming is a craft. Craft your applications wisely and you'll never go wrong (unless you're looking to trash-talk something using bad science and worse code).

Laterz!

Dude, please try to be accurate.

People who skew the truth and deliberately mislead people make me angry. This post is a direct result of that phenomenon. If I sound irritated, well, it's only because I am. People who make a deliberate attempt to denigrate any platform based on artificial or manipulated results need to be called out on it. Letting a lie grow is, in my opinion, the same as telling it yourself...

In a recent post on his blog, Mr. Phil Parsons, self-professed CF "disliker" ("hater" seems a bit strong lol) and PHP aficionado, released several bits of code that claimed to demonstrate ColdFusion's performance inferiority to PHP. So I decided to see what was up with that myself. I wanted to see if it was true. I would have been happy to report that, yes, PHP is in fact faster than ColdFusion, here's my results. However the more I experimented and optimized both the PHP version and the ColdFusion version, the angrier I got about Mr. Parsons' blatant misrepresentation of the facts.

(NOTE: I didn't want to disprove him, I wanted to find out if it was true. If it's true, so what? This was a thought exercise, not an attempt to redeem ColdFusion (which really doesn't need redeeming anyway!))

Much thanks to Elliot Sprehn for helping me get a decently optimized prime number scanner that's practically bit-for-bit identical between PHP and ColdFusion. It's funny, because even his PHP code was pretty poorly written. According to the Mr. Parsons, the best PHP could do to calculate prime numbers up to 10,000 was 128ms. According to our optimized version of the scanner, PHP is capable of calculating prime numbers up to a value of 10,000 in 11.51ms.

Here's where the results get interesting:

ColdFusion, pathetic, ugly, poorly performant ColdFusion, despised and unpleasant to write with, actually did the same thing in 8.214ms.

Sorry Mr. Parsons... your "benchmarks" suck. ColdFusion is a full 3 and a quarter milliseconds faster!

I'm sure this will make or break a preponderance of web applications currently in development. /sarcasm

And incidentally, Mr. Parsons' professed goal with his post was specifically to prove ColdFusion inferior to PHP.

Ooops.

The test platform was:

  • Hardware: Apple MacBook Pro 2.8 GHz Core II Duo w/8GB RAM
  • Web server: Apache/2.2.15 (Unix) x64 (OS X Snow Leopard Default)
  • PHP: PHP 5.3.3 (cli) (OS X Snow Leopard Default)
  • CFML Engine: Adobe ColdFusion 9.0.1 x64 on JRun 4

And, for the record, none of the 3 server components were optimized in any way. Out-of-the-box and go.

Here's the code I used for each:

PHP:

view plain print about
1<?php
2
3function & primes($to) {
4 $primes = array(2, 3);
5 for ($i = 5; $i <= $to; ++$i) {
6 $root = sqrt($i);
7 for ($j = 0; $primes[$j] <= $root && $i % $primes[$j] != 0; ++$j);
8 if ($primes[$j] >
$root) {
9 array_push($primes, $i);
10 }
11 }
12 return $primes;
13}
14
15function arrayAverage($array) {
16    return array_sum($array)/count($array);
17}
18
19$times = array();
20
21for ($i = 0; $i < 1000; $i++ ) {
22    $t = microtime(true);
23    $primes = primes(10000);
24    array_push($times,microtime(true)-$t);
25}
26
27echo number_format(arrayAverage($times) * 1000, 5) . " miliseconds for " . count($times) . " iterations.";
28
29?>

Didja notice I had to roll my own average function? WTF?

ColdFusion:

view plain print about
1<cfscript>
2function primes(to) {
3 var primes = [2,3];
4 for (var i = 5; i
<= to; ++i) {
5 var root = sqr(i);
6 for (var j = 1; primes[j] <= root && i % primes[j] != 0; ++j);
7 if (primes[j] >
root) {
8 arrayAppend(primes, i);
9 }
10 }
11 return primes;
12}
13
14times = [];
15for (c=1;c<=1000;c++) {
16    start = getTickCount();
17    primes(10000);
18    arrayAppend(times,getTickCount()-start);
19}
20writeOutput( arrayAvg(times) & " miliseconds for " & arrayLen(times) & " iterations.");
21</cfscript>

cf.Objective() 2011: Doing things a bit differently and need your help!

Oh yeah, we're still here, baby!

cf.Objective() 2011 is on, but we need your help. This year rather than broadcast the same old brute-force "Call for Speakers" concept, we've decided to do things a bit differently. We've got a new application up, courtesy of Matt Woodward and Bob Silverberg, and we're requesting community input on the topics you'd like to see at the conference this year.

(As an aside, this explains our delays this year. New board, new technology, and a new way of doing things. It's taken some time to get all our ducks in a row and they're finally quacking their little brains out... let's not disappoint them? I hear bored ducks can actually make quite the ruckus!)

Please, please, please, please! (or: The WHAT)

So please go here and suggest topics. Any topics. Well, any CF/Adobe relevant topics, anyway. Any level of expertise, any technical level. I can't (read: won't) make any promises except for this: We'll put on the same top-notch, highly professional conference we have every year for the last 5 years. We just want to see what YOU want for content this time. But we really really need to gauge the need out there this year and without your input we can't do that.

And please tell your friends. Tweet it. Facebook it. Plurk it. DIGG it. Whatever. But we need to get the word out and get as MANY ColdFusion professionals contributing to the data. I can't stress enough how important this is to the ongoing success of cf.Objective(). Why is this so important? Why? Why? Why?

The WHY

Well, here it is, straight up: The primary motivation for doing things this way this time is, to be honest, the demise of CFUnited. CFUnited left a huge hole in the ColdFusion educational world, especially for government. However CFUnited also served a somewhat different audience than we have, traditionally, served. Now, before anyone spontaneously combusts at the thought of cf.Objective() becoming a beginner/intermediate conference, that ain't gonna happen... exactly.

The HOW

We're looking at adding a track, a pre-conference, an unconference or any number of other solutions or combinations that would allow us to serve the disenfranchised client base that CFUnited left behind... but we can't do that till we know what the interest levels are for at least intermediate topics, but if we had enough call for it we'd consider doing some entry-level content as well. We're already adding a track for those who aren't quite at a skill level typical of our traditional audience but want to be... something like "So you got no wings but you want to fly?"

What we need to determine is whether we need to make the conference longer (more days or more hours in the day), wider (more tracks, more simultaneous sessions), or some other approach entirely. But we can't do that at all until we know what kind of content people are wanting us to deliver. We have the resources and the connections to deliver whatever you want or need, and you're our customers. So we're asking you: What information can we collect for you that will make your workdays smoother and your off-time so much sweeter?

The END

That's it, that's all, folks. We need you to contribute some input to the conference so that we can make it the best, the smartest, the hippest, rockin'est ColdFusion conference in the whole day-gone world... well, except Australia because we don't want to compete with cf.Objective(ANZ) because that'd be like shooting yourself in the foot. Right? So unless you're from there, or somewhere near there, like New Zealand or Antarctica or something, please go fill out our survey. Well, I mean unless you would RATHER travel for 13 weeks and spend the whole time standing upside down... ;)

OK, seriously, please, go to Engage and do your thing!

Laterz!

cf.Objective() 2011! YES!!! YES!!! YES!!!

I know there's been some speculation lately as to whether or not cf.Objective() was even on for 2011. With the demise of CFUnited, it speculation to that effect would make sense... conferences are passé, right? It's all about the freebies, the mini-cons, the one-day luncheon-style get-togethers. Well, let me say this:

The rumors (if there are any) of our demise are greatly exaggerated!

I'll be posting news and information about the conference here as time passes, but I just wanted to note that the dates and venue have been posted on the cf.Objective() site. We're at the same Hyatt Regency in downtown Minneapolis that we were last year, and our dates are May 12-14, 2011, for your planning and resource-gathering edification.

In other news...

I'd like to welcome a few new members to the Steering Committee:

  • Bob Silverberg (our new content chair)
  • Stephen Withington (content chair)
  • Jason Dean (member at large)

These intrepid souls join the existing rag-tag crew for what is both a pleasure and a huge sacrifice... we owe them a great deal of gratitude.

Oh, and that "existing rag-tag crew" consists of:

  • Steven Hauer (co-chair)
  • Jared Rypka-Hauer (co-chair)
  • Barbara Louis and Jim Louis (mother-son power team from Best Meetings, Inc., and they are the Best!)
  • Andy Pittman (member at large)
  • Matt Woodward (member at large)

Without the folks who put so much effort into this conference, it really would never happen.

So!

Mark your calendars, keep your eyes peeled and your RSS readers tuned, and we'll keep you posted as things move forward.

And that, as the bard has said, is the rest of the story.

Laterz!

Windows Advanced Query Syntax -- cumbersome, but useful!

Remember back in the Windows 2000 and Windows XP days? Hit F3 and have a set of fields you could type in to find about anything? Well in Windows Vista and Windows 7 that's gone and the search UI is utterly atrocious. Enter AQS.

There's more on the subject here, but it looks like a SQL-esque sort of filtering syntax to let you narrow down your search results.

Let's say you want to see all the JPG or PNG files starting with the letters "map" under the normal Windows webroot:

view plain print about
1folderpath:C:\InetPub\WWWRoot\* filename:map ext:(jpg OR png)

It took me 45 minutes to figure that out. Thanks MS. "Efficient" you are not, but at least you've provided a way to do this since you stripped all the decent UI for doing searches out of Windows after XP. Until I added the parens around the file extensions it found all the JPGs with MAP in the name and ALL the PNG files in the folder. Also not that without the wildcard at the end of the file path it only searches that folder... you have to add the wildcard to have it search the entire tree (actually kinda nice if you have a set of folders with a common portion of the name). Also interesting is the fact that "map" is the same as "*map*".

I guess this is gonna take a while to get used to... but since I'm stuck on Windows 7 at work, I suppose I'll figure it out. ;)

Oh, and there is a semi-decent AQS reference at the MSDN page on AQS. At least it's more complete than the link at the beginning of this post.

Laterz!

CF Builder tip: add vhosts to servers in bulk!

Our main project at work is a work in progress... it's old, and it uses subdomains to trigger changes in the way the codebase is handled. What that means to builder is having one instance of CF powering a great many vhosts. Now, I dunno about you, but I REALLY hate adding vhosts to Builder using the panel in the Server properties. But, I'm here to tell you, there's an easier way!

Before you do this, please backup your workspace folder. /silly disclaimer

If you go into the folder {workspace}/.metadata/.plugins/com.adobe.ide.coldfusion.server you'll find a file called Server.xml. The first issue you'll have is that the XML is entirely unformatted. If you're not using an XML editor that supports automatic formatting, try using a text editor that supports regex find/replace and replacing "><" with ">\r\n<" on Windows or ">\r<" on OS X.

If you open that file up, you'll see your configured servers. Each server contains quite a number of properties, more than I can really deal with right now. But, if you have already configured one vhost, you should see a subtag of called . That should have your vhost block sitting there smiling at you, waiting for you to duplicate it. The contents look something like this:

view plain print about
1<VirtualHosts>
2    <VirtualHost>
3        <Name>My Nifty Virtual Hosts</Name>
4        <Address>wibble.mydevserver.dev</Address>
5        <Port>80</Port>
6        <Location>C:\inetpub\www\wibble</Location>
7        <EnableSSL>false</EnableSSL>
8    </VirtualHost>
9</VirtualHosts>

You can now duplicate this section and fill your own values in for the properties.

There is one very crucial gotcha!

CF Builder does a couple interesting things that could really mess you up if you're not aware of them. First, all configs are read when the app starts up, so you need to have these changes in place and THEN open Builder. Also, when you exit the program, it flushes all the settings to disk, so if you edit the Server.xml file with Builder, save it, and then exit the program, you've just lost all your changes. So you need to either shut Builder down and use a different editor to make the changes, or you need to edit the file, do a Save As... outside the workspace folder, then copy it over the one that's there by hand.

Once you've got the changes saved to disk and the edited file in {workspace}/.metadata/.plugins/com.adobe.ide.coldfusion.server, you can start up Builder, double-click the server in the Servers tab and take a peek at the Virtual Hosts section of the second page. You should see that you've just saved yourself a great deal of effort by editing the config file directly rather than using the futsy-putsy UI.

Either way, I just added 11 vhosts to my server config using copy/paste/change instead of 45 minutes of tabbing, clicking and complaining.

Laterz!

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9.7. Contact Blog Owner