Friday 31 May 2013

Passing a complex object to a ColdFusion RESTful web service

G'day:
I googled everywhere for how to do this, and drew a complete blank. I had to fall on the mercy of a friendly Adobe engineer to help me get it working, so I thought I would knock together a quick article so if anyone else ever needs to do this, there's something for Google to find.

Firstly, I gotta say that on the whole I probably would not create a RESTful web service which accepts a complex value... it seems to make more sense to me to work with simply types, and perhaps reflect any complex nature using collections of simple-value fields, or JSON or something. Still: I had this specific requirement which was out of my hands, so I needed to make it work.

Thursday 30 May 2013

ColdFusion / Railo WebSockets: do you use 'em? (survey)

G'day:
I've just started looking at the technical side of the WebSocket offering in ColdFusion 10. It's an interesting-looking technology, but I'm just wondering what real world practical applications people are putting them to. I've seen plenty of "chat demos" and the like, but nothing that one would really want to do in the real world. So I'm just gauging the community's usage of them.

As far as I can tell Railo doesn't have WebSocket supprot built-in, but there's a WebSockets Extension. I've not tried it. But I will at some stage.

Anyway, I want to know about your usage of WebSockets, or also if you've not used them and/or have no interest in them at all. I've knocked together a quick survey (four questions). If you fancy filling it in: good for you, and thanks. If you feel like re-sending the Twitter message I will send out advising of said survey, that'd be cool too: the more responses the merrier.

Cheers.

--
Adam

Wednesday 29 May 2013

CFML: Application.cfc look-ups and virtual directories (Appendix)

G'day:
Yesterday I did a bit of an investigation in to how ColdFusion looks for an Application.cfc / .cfm when it runs a request. This article is a continuation of that, and it won't make any sense if you don't read yesterday's article first.


In yesterday's article I had this directory structure set up:

C:\
  apps\
    adobe\
      ColdFusion\
        10\
          cfusion\
            wwwroot\
              docroot\
                test.cfm
                some_dir\
                  linked_subdir\
                    test.cfm
                  local_subdir\
                    test.cfm
  temp\
    linked_subdir\
      test.cfm

And I covered the look-ups for Application.cfc from both local directories, and junctioned / linked directories.

Following my Twitter feed this evening, and Laura Springer (who I don't know, other than from following on Twitter: I hope you don't mind me using you as an inspiration, Laura) made an observation about Application.cfc file behaviour when called from a virtual directory.

And it occurred to me that this is:
  1. something I didn't cover in my previous article;
  2. another thing I didn't know the behaviour of.
I won't carry on as much as I did last night, but I set up this modification to the above directory structure:


C:\
  apps\
    adobe\
      ColdFusion\
        10\
          cfusion\
            wwwroot\
              docroot\
                test.cfm
                some_dir\
                  linked_subdir\
                    test.cfm
                  local_subdir\
                    test.cfm
                  virtual_subdir\
                    test.cfm
  temp\
    linked_subdir\
      test.cfm
    virtual_subdir\
      test.cfm

Where C:\temp\virtual_subdir is a physical directory mapped into the site via a virtual directory /some_dir/virtual_subdir/.

I'll not do all the colour-coding and stuff from last night, but when browsing to /some_dir/virtual_subdir/test.cfm, ColdFusion looks for Application.cfc / .cfm files in the directories as listed below:

Default

C:\temp\virtual_subdir\Application.cfc
C:\temp\Application.cfc
C:\Application.cfc


Until Webroot

C:\temp\virtual_subdir\Application.cfc
C:\temp\Application.cfc
C:\Application.cfc


In Webroot

C:\temp\virtual_subdir\Application.cfc
C:\apps\adobe\ColdFusion\10\cfusion\wwwroot\docroot\Application.cfc


So as you can see here: for the first two options it looks up in the physical directory structure, but in the latter example it looks in the immediate physical directory, and then looks in the web site's web root (and no further).

Another curious thing... you know how yesterday I said that the "web root" for the purposes of this look-up meant "the ColdFusion root", not the web server / site's web root? I tested that assertion three times last night, and was 100% confident I was correct in saying that (I checked because it seemed to be contradicting what I was reading elsewhere on the 'net, so presumed initially I was wrong). However this evening having seen what seemed like anomalous behaviour with that last path on the "in webroot" look-up, I tested again. And for the life of me I cannot replicate last night's behaviour this evening: this evening "web root" means "the web site's web root" not "ColdFusion's application root". There's a chance I screwed up last night, but I really don't think I did. Well: 80% sure I didn't. However I could have got something wrong. I'm gonna put a caveat on last night's article until I test more thoroughly, and make myself sure of what's what.

That's all I have to say on that. I had better go put a warning on y/day's article to the effect that I might be talking ballocks. Well: more so than usual, I mean ;-)

--
Adam

Tuesday 28 May 2013

CFML: Application.cfc look-ups and linked directories

G'day:
This is a pretty non-descript topic / article, sorry. Someone raised a question on the Adobe ColdFusion forums about the possibility of CF10 not getting along well with Application.cfc look-ups from within a symlinked directory. I doubted this would be an issue, but I wasn't 100% sure so I thought I'd check it out.

Links / junctions
Before I start, just in case you're unsure about symlinks, here's what Wikipedia has to say about them. These are pretty prevalent on *nix systems, but they're under-utilised on Windows. Mostly because people are unaware they exist. Windows has actually been able to effect pretty much the same thing as a symbolic link since Windows 2000. Well: the Windows GUI shell couldn't, but the underlying NTFS file system has supported junction points since Windows 2000 came out. And a junction point amounts to the same thing.

Junction points are bloody handy. I have quite a number of CFML app servers running on this machine: CF5, CFMX7, CF8, CF9 (multiple instances), CF10 (multiple instances... Railo Express, some manner of OpenBD install (gathering dust)... and they all have their own discrete webroots for platform-specific stuff (eg: C:\webroots\cf5, C:\webroots\railo-express, etc). However I have a repository of all my common code @ C:\webroots\shared. Into each of my version-specific webroots I junction-in a reference to shared, so I have C:\webroot\cf10\shared etc. As far as CF10 is concerned, C:\webroot\cf10\shared is a discrete directory. And as far as Railo is concerned, C:\webroots\railo-express\shared is a discrete directory. But it's all the same place. Cool. I dunno how to create these things on *nix (something to do with ln comment), but , but on Windows it's just this:

C:\webroots\cf10> mklink /d shared c:\webroots\shared

Where obviously "shared" is what the junction ends up being called, and c:\webroots\shared is where it points to.

I've never had any problems with these on ColdFusion or Railo, and have been using them for a decade.

Anyway, that was a digression. Another side issue that came up from the original question is how does CF look for which Application.cfc (or .cfm in the case of the original question) to execute, for a given request. I'd forgotten that there were multiple "modes" for doing this settable in CFAdmin, and had never really paid much attention to them, so decided to roll both these concepts / questions into one investigation.

Firstly, lets look at the options on offer in CFAdmin:

As various people have blogged, docs on this setting are a bit thin on the ground, so I can reproduce it in its entirety without blowing out my word count:

Select the order in which ColdFusion searches for Application.cfm or Application.cfc if it is not found in the current project folder. You can set ColdFusion to search as follows:

  • default search order: ColdFusion looks for an Application.cfc/Application.cfm file from the current folder until the system root directory. On Windows, this could be C:\ and on UNIX, /opt.
  • till web root: ColdFusion looks for an Application.cfc/Application.cfm file from the current folder till web root.
  • in web root: ColdFusion looks for an Application.cfc/Application.cfm file in the current folder or web root.
And that's all there is to it. I think perhaps the guidance is wrong for *nix... surely / is the root, not /opt? I suppose it depends on permissions, but the same could be said for the /opt dir as well. And "till"? Sigh. But anyway. There's also another significant terminology error in there, but I'll get to that.

To demonstrate each of these, I have set up the following directory structure on my box:

C:\
  apps\
    adobe\
      ColdFusion\
        10\
          cfusion\
            wwwroot\
              docroot\
                test.cfm
                some_dir\
                  linked_subdir\
                    test.cfm
                  local_subdir\
                    test.cfm
  temp\
    linked_subdir\
      test.cfm

There are several significant elements to this:
  • The root
  • The ColdFusion instance directory
  • The ColdFusion app root - CF serves files from within here
  • The web root - the web server serves files from within here
  • A junction
  • The directory that is junctioned
  • Test files
In the table below, I highlight where ColdFusion will look for an Application.cfc or Application.cfm (it'll be one or the other, in that order of precedence, btw), given the specified file being requested.

Scotch on the Rocks: which sessions am I going to?

G'day:
Meself and a bunch of the bods from work are off up to Edinburgh for Scotch on the Rocks 2013 next Weds. I should be lurking about from about 2pm, I guess.

I've not even looked at the schedule yet, but "what are you going to see?" came up over cheap-steak-lunch-at-'Spoons just now, so I figured I'd better find out.

So in a similar vein to my cf.Objective() article on the subject... here's my thoughts on which sessions I might go it.

Sunday 26 May 2013

Ruby: doing a second tutorial @ codeschool.com

G'day:
OK, I'm coffee`d up and am gonna do the next Ruby tutorial. Yesterday I did "Try Ruby", and now I'm on the second leg of the Ruby path "Ruby Bits". As a recap: I'm suddenly doing these Ruby courses because codeschool.com is offering their services for free this weekend. I have 16hrs of freeness to go, so I hope to get through two courses.

Saturday 25 May 2013

Ruby: stream-of-consciousness

G'day:
OK, so I'm fiddling around with Ruby (as per my previous post), and am typing this article as I explore.

Prior to starting this I googled "ruby IDE", and saw a lot of advice from people to just use a text editor. There are always people who claim they do all their code in notepad or vi etc, and I always figure they're just trying to sound cool. Whereas I think they just sound stupid, because whilst anyone can type code into a blank, featureless typing window (and we've all had to do emergency hacks on prod servers using vi or notepad, so it's good to not have to rely on code assist, etc), it's not exactly the most professionally productive way of going about one's business.

It seems like the general opinion is to use the plug-in for NetBeans, or a plug-in for Aptana. The plug-in for NetBeans has been discontinued (although someone's blogged how to install it anyway... I might need to look at that later on), so I have installed Aptana as a plug-in to Eclipse, adjacent to my ColdFusion Builder plug-in. This seems to have had the effect of slowing down Eclipse even more, and interfering with my Eclipse config, so this has not impressed me one bit.

One of the Aptana pages I landed on suggested install Ruby via RubyInstaller, which I duly have done, and that all seems to work, which is cool.

I dunno how to do all the IDE-y stuff yet, but I can create a Hello World file and run it from the command line.

Ruby via codeschool.com

G'day:
Cheers to Ray Camden for putting me on to this, but Code School are offering free online training all weekend, thanks to some outfit called New Relic sponsoring it. Yay for Code School & new Relic!

I was planning on doing some summery stuff like going into the forest and getting a decent dose of greenitude and vitamin D, but it's bloody freezing (10degC @ midday, about a week from the start of "summer"!) so I'm staying indoors and am gonna work my way through the Ruby courses they offer. If I find anything interesting - which I presume I will - I'll write it up.

However I had better also dose up on various forms of caffeine first, as I've already sat at this blimin' computer for 4h today, and my attention span is waning.

Wish me luck (not with the Ruby, but with not freezing to death en route to the station for a coffee ;-).

--
Adam

212 untriaged ColdFusion 10 bugs

G'day:
I saw this on Twitter last night, and - predictably - it f***ed me right off.

Friday 24 May 2013

Gotchas when upgrading ColdFusion 9 to run on Java 7?

G'day:
Just a quick one... have you upgraded you ColdFusion servers to run on Java 7? If so, did you encounter any problems / issues / unexpected behaviour?

I'm gonna be involved in an upgrade of a largish 9.0.1 installation from Java 6 to Java 7, and want to gather info about what to possibly expect.

It'd be really cool if you could let me know about your experiences, and it'd be even better if you could circulate the Twitter message I'll be sending to notify people of this article, so I can gather as much input as possible.

Thanks!

--
Adam

Identity change continues

G'day:
My mission to neutralise my CFML-oriented social media presence continues. As well as the blog name and domain change (which you probably know about / have noticed by now), I've also changed my contact email address (now dac.cfml@gmail.com. This has changed as well, however I'm not publicising the new one; you'll need to already know it, or spend 5min finding out), and my Twitter name: dacCfml DAC_dev (Twitter won't allow fullstops in one's account name).

If you've ever wondered where the "dac" part comes from my former Twitter account name (daccf), and now in these new accounts, it's because my first name is actually Donald. So those are my initials: Donald Adam Cameron.  My folks had a disagreement (well more a failure to agree, rather than a disagreement, per-se) over what my first name should be: Dad wanted it to be "Donald" (his name), Mum wanted it to be "Adam". So they compromised, and my first name is Donald, but in casual circles I go mostly by "Adam". In official circles (banks, govt, etc) I remain "Donald". I answer to both. Well: I answer to almost anything people choose to call me: I'm not fussy.

I actually think it's quite cool because I get usage out of both my forenames, and I consider myself both a "Donald" and an "Adam", whereas most people only really think of themselves by their actual first name, and any other forenames they have are just noise.

The only real side effect of the email account change is that you might get a Google+ / chat "invite" from that account. So if you see this happening, you know why. Or if I'm not already in Google contact with you, by all means: add me in.

Righto.

-- 
AdamDonald

Thursday 23 May 2013

PHP: glob() and how PHP's design-by-random-contribution sux

G'day:
A coupla weeks back I undertook to write some code to emulate a web server directory listing in PHP. And having written the code I offered it up for code review on Stack Exchange's Code Review subsite.

I didn't get much feedback, and on the whole it was (at least partially misguided ~) advice on the logic, rather than the PHP (so missing the point of what I was asking), but there were a coupla interesting things to take away from it.

Tuesday 21 May 2013

New Domain & new blog name

G'day:
I wasn't quite ready to go live with this, but GoDaddy and Blogspot are more efficient than I hoped they would be, and everything(*) is already redirecting.

So the URL for this blog will now be http://blog.adamcameron.me. Old Blogspot URLs should all be redirecting to that now.

cf.Objective() day 2&3 - brain dump

G'day:
My health faded a bit on Fri & Sat (some of this was self-induced - especially Saturday - but my man flu was getting the better of me), so I'll roll the latter two days into one article.

Sunday 19 May 2013

cf.baseball()

G'day:
Apropos of not much, here's a badly exposed photo of the cf.objective() bods who have come along to the Twins v Red Sox game:



What a very very shady bunch they are. Update: I've changed to a much better photo... one in which one can actually tell who the people are!

We're currently sitting at the bar at the game. Great fun, great new friends, great conference.

Time for another pint...

--
Adam

Saturday 18 May 2013

Another Railo feature for developers: linked structs

G'day:
This extends from my article about a Railo enhancement to replace(), yesterday.

One of the things I observed about the new replace() feature is that given it takes a struct to map its replace-tokens with its replace values, one cannot guarantee which order the replacements are made. This is because structs have no sense of order in their keys, so one ought not infer one or write any code which depends on a sense of ordering in the struct. Here's an example of what I mean:

Friday 17 May 2013

OK, another handy new Railo feature

G'day:
I have some downtime @ cf.Objective() at the mo', so looking at some of the stuff Gert showed us in his presentation. It's that or have a beer... but it's perhaps slightly too early for that. Maybe... hmmm. Anyway, whilst I mull over having a beer, I have this article in my head, so I'll type it in.

Enhancement to replace() in Railo 4.1

G'day:
Gert Franz has just given a very impressive presentation on some new features Railo has added in 4.0 and 4.1. There's too many to go through, but here's one that interested me.

In Railo, the replace() function can now take a struct containing key/value pairs which represent the substitution tokens / values to replace. EG:

cf.Objective() day 1 - brain dump

G'day:
OK, I'm fed up with staring at the ceiling fr the last 3h since I woke up around 4:30am (or "9:30am, you lazy bastard, get up" as my still-UK-homed brain was telling me), so I'll knock out a quick article on my thoughts on yesterday's Day 1 of cf.Objective().

Tuesday 14 May 2013

Improving ColdFusion CFML's OO-ness

G'day:
This has probably done the rounds before, but it's just put itself back within my sphere of attention, so I thought I'd mention it. It's also a good quick article to write from bed as I desperately try to ditch a cold I picked up in Ireland; before I have to sit on a plane for 9h tomorrow, to get to cf.Objective() (cue: sympathetic violins). I'm buggered if I'm gonna be hamstrung in my networking (read: beer consumption and general revelry) by a bloody sniffle.

Anyway, I just raise an enhancement request (3559652) for ColdFusion, thus:

Saturday 11 May 2013

Interface inheritance what one can and what one cannot do

G'day:
Today's article is brought to you via my baby netbook, as I sit on my bed in my hotel room in Portumna, Co. Galway in the the Republic of Ireland. My ex-wife and my son (25-months-old) live in Portumna, and this is why I pop across to Ireland every two or three weeks (you might have heard me mention it on Twitter or elsewhere). I get to see my boy for four hours on Sat and Sun, every - as I said - 2-3wks. This sux, but that's the way it is.

I only have internet here if I go sit halfway down the stairs, and despite that being doable as I'm the only guest here this weekend, it's a bit cold for that today. So I'm writing this article without the benefit of docs or fact checking! Wish me luck. Or enjoy picking apart whatever it is I end up getting wrong. Heh: in reality I will check everything before I publish... the internet works in the bar downstairs, so I'll proof-read and publish over an early evening Guinness.

Thursday 9 May 2013

We interrupt this service...

G'day:
Well actually: no, it's not "we" who have interrupted any service.

However I'm afraid to say a few small community-oriented services I run are currently down.

A coupla bits of curious behaviour

G'day:
Here's a coupla bits of code that undid me yesterday. What do you make of these code examples:

Wednesday 8 May 2013

A quick note on spamming/abuse on my blog


I am nonplussed.

An Architect's View: Sean's feedback on my recent article about ColdFusion interfaces

G'day:
It's a good day for this blog when someone like Sean Corfield reacts to something I write with an article-sized response in the comments. I've asked him if it's OK to reproduce this as a "guest-author" article, which he's agreed to. I did this because I freely admit I'm making up my opinion regarding ColdFusion's interface implementation as I go along, whereas Sean knows an awful lot about the subject - and had a hand in their genesis - as far as CFML goes. So if I'm discussing this topic, his opinions are important ones to reflect upon.

Below is a reproduction of his comment posted against my article entitled "Interfaces in CFML. What are they for?". I have some opinions on this - actually most are "yeah, good point" - but I'll cover them in a separate article.

Thanks, Sean, for taking the time to write this:

A case for interfaces in CFML

G'day:
Yesterday I slapped together a reasonably incoherent article discussing the very basics of how interfaces are implemented in CFML, and tried to give an example of where one might consider using interfaces rather than fall back to class inheritance. Basically my take on interfaces is that they define a behavioural or integration contract, rather than define what it is to be an object (which is what the CFC itself defines).

Tuesday 7 May 2013

Interfaces in CFML. What are they for?

G'day:
Now this will be an interesting one. Not "interesting" as in "fascinating" but "I dunno what I'm gonna write yet, so it'll be interesting to see what I come up with". So possibly more interesting to me during the writing process that to you during the reading process.

I've just been having a conversation on Twitter about interfaces (ie: the <cfinterface> kind), and I recalled that at some stage I was gonna have a look at them in depth to completely get my brain around them. This notion predates this blog, but it's been something I've meant to cover at some stage.

Monday 6 May 2013

PHP: Getting PHPUnit up and running

G'day:
Before I write too much PHP code, I want to get my TDD environment sorted out. Prior to my current job, I'd never done unit testing before (cringe), but I'm well onboard with it as a concept. Initially it seemed arse-about-face to write tests for code that doesn't exist yet, but it really is a good approach to writing solid code, and not going to OTT with features one doesn't need (or doesn't need yet), as it makes for more testing before the unnecessary code gets written. And much as I'm OK with writing tests, I only want to write what's necessary.

I have to admit that for my after-hours work I only write unit tests for about 50% of it, and I generally write them afterwards. Mostly due to slackness, and mostly due to not really caring whether my code for this blog and other things I potter around with works robustly. But any work I do for paying clients gets written in a correct TDD fashion. And they get charged for it, and they're happy with doing so. I hasten to add I do very very little paid-for work in a "moonlighting" capacity, indeed have not accepted any for a coupla years now.

Sunday 5 May 2013

What I plan to see @ cf.Objective()

G'day:
Apropos of not much, here's how my thoughts on what I intend to go see @ cf.Obejctive() are currently falling together. All, obviously, subject to change.

Weds

Alex and I won't be getting in to MSP until around midnight (ie: at the end of Weds), so I'll be missing all the pre-conf socialising, unfortunately. Because I lack common sense and good judgement when it comes to whether or not it's an appropriate time to have a beer, I might sniff around to see whether anyone is still propping up the hotel bar. Although I will have just got off 10h of flying, and my brain will be saying "it's 6am", so I dunno. We'll see.

Saturday 4 May 2013

Code Review

G'day:
I became aware of Stack Exchange's Code Review website a few months back, but never really looked at it until today. I decided one way to get someone other than Bruce (no offence! ;-) to look at my PHP code would be to chuck it up there and see what happened. Well so far nothing has, but it's the weekend etc, so perhaps people have better things to do than review my code on the weekend. How this can be true I don't know, but the world is a funny place.

Anyway, they have a ColdFusion / CFML channel too, so it might be a place to chuck yer code up there to get reviewed.

Follow-up to "Quick Code Puzzle" article

G'day:
I'm a bit disappointed that I only got three responses to my code puzzle the other day, but so be it. At least Matt, Dale and Winston will get a beer next time I see them. Thanks guys: I really do appreciate you taking the time to join in.

Bruce: cheers for your response, but you didn't actually post a solution, so you weren't in the running for a beer!

To recap, the problem was to write this function:

boolean function isWithinWebroot(required string fileSystemPath){
    // provide code here
}

Friday 3 May 2013

PHP: solving a real problem

G'day:
As you might have read, I discovered PHP has an internal web server, just like CF does. It seems a lot more basic than ColdFusion's one... especially the one that CF10 uses which is pretty much production-quality.

One thing I have not been able to find out how to do is to get it to list the contents of a directory, as one can enable on Apache / IIS etc. I'm pretty sure it doesn't support this functionality at all, as the docs mention a few options, but not that.

Thursday 2 May 2013

cf.Objective()

G'day:
In a surprise move... I am going to cf.Objective(). So that's quite cool. My mate Alex Skinner is heading over from Blighty too, and he convinced me to tag along. The lads (and guests) from CFHour also had a hand in convincing me I really ought to make it, as the presentations people described they're giving sound excellent.

Wednesday 1 May 2013

Quick puzzle: is this path within the doc root?

G'day:
Here's a code puzzle question.

Write a function thus:

boolean function isWithinWebroot(required string fileSystemPath){
    // provide code here
}