Dominic Cronin's web log
A noteable namesake
Apparently, I have a noteable namesake; there was a Dominic Cronin who played cricket for Ireland. Who knew?
http://www.cricketeurope4.net/CSTATZ/irelandall/bio/c/cronin_d.html
Time for a new kernel on the gentoo server.... again
Living with a Gentoo Linux installation is sometimes a bit like being on a runaway train. Of course, it's great that the portage system gives you the possibility to keep your operating system right up to date, and manages all the dependencies between the various libraries as each in turn gets upgraded. But.... it doesn't take much experience with this to realise that automatic dependency management of such a complex system is best done in small doses. So you sync and update "world" pretty often, so that the changes being integrated on any given occasion are limited to a manageable amount. Sometimes you have to intervene to resolve circular dependencies by hand, but not so often that it's really painful.
So you keep your system up-to-date. No need to join the fanatics and do it every day, but whenever you remember... a couple of times a week? Libraries get updated automatically, but the kernel is rather different. You have to build and install a new kernel yourself, albeit with fairly good automatic tools. Mostly, you don't do it unless you have to. In my case, I definitely don't do it unless I have to, because my server sits in a cupboard under the TV in the living room. It doesn't have a monitor of its own, and I usually access it across the network from one of the other computers. If it won't boot properly, there won't be any network connection to use, and I'll end up carrying the monitor from my desktop box up the stairs, and sitting in front of the telly trying to get things working again. Guess what? Kernel upgrades usually don't work first time, so I end up having to go through this rigmarole so that I can boot a different kernel so that I've got a working system to work on, so to speak. (This time was no different, but I'll come to that.)
So you put it off.
I'd been upgrading the rest of my system for a while and living with a slightly out-of-date kernel, but then I started getting warnings that key features of the system needed a more recent kernel. Specifically, the udev sub-system, which takes care of dynamic device management, needed to have a very recent kernel. I built and installed the linux 2.6.31 kernel, and rebooted the machine.
I tried to connect to it after the reboot, and as I'd sort of expected, no joy. After the routine of humping the 19" CRT monitor up the stairs, I could see that the failure to boot was caused by a kernel "panic" (don't you love it?)... something to do with VFS... cannot open root device "hda3" or unknown block (2,0) - great eh? (So just for the record, when we say Linux is for "amateurs", we mean this literally!) My first thought was that I had failed to compile in kernel support for the file system of the boot partition, but no, that was fine. It turned out that with recent kernels, disks aren't called hda1, hda2 etc., but sda1, and so forth. Who knew? So I had to edit my boot configuration (grub.conf) to account for this change, and at the same time edit /etc/fstab to mirror the same changes. This was scary, because if the system hadn't come up this time, I'd have had a machine that wouldn't boot from either the old or the new kernel, and I'd have been fishing around with a livecd boot and a chroot shell (give me strength!).
Still - nothing to lose, and everything to gain, I tried it and it worked. I now have a working system again. (Kudos to NeddySeagoon of #gentoo, whose technical advice got me through with surprisingly little trauma.)
Then yesterday, I decided for a rare treat to lash out 10 euros on the March edition of Linux Journal. In the letters page there's some person called George banging on about how in the aforementioned letters page: "more often than not there is an end user who knocks Linux as being for 'computer specialists' and not ready for the mainstream". George finds this attitude unfortunate. News flash, George: It's not the attitude that's unfortunate, but the facts behind it. [And before anyone says Gentoo Linux is a masochist's distro (or whatever), the folks using Ubuntu have had exactly the same problems with hda/sda.]
Sure, there are Linux distros that can work pretty nicely for normal end users. Unfortunately for the rhetoric, the only normal people using Linux aren't well.. normal. That simple choice sets them apart. Normal people just go out and pay the fifty quid extra (I'm guessing) for an OEM license when they buy their computer, and just run Windows. Ironically, because most of those people aren't actually upgrading, one of the things they are paying for is an incredible upgrade experience.
What am I saying? OK - it isn't exactly abnormal to service your own car, or fix your own dishwasher, but it isn't mainstream. Neither is Linux. These days, you can't service your own car even if you want to, because instead of a distributor it's got some slab of solid-state mystery. At least with Linux, if you're daft enough, you can read the source code of the disk device drivers in the kernel. Good luck though.
Anyway - for this amateur at least, no need to drag the monitor upstairs for another few months. I hope.
More on code re-use and libraries.
Back in June, I wrote a blog post in reaction to Udi Dahan's "The fallacy of ReUse". Now Mark Needham has published a blog post with a very similar theme. One interesting insight is that sometimes sharing domain objects can be dangerous, because as he puts it "although we often do have the same domain concepts in different projects, it's quite rare that they mean exactly the same thing".
SDL Tridion MVP award
Today the official announcement has been made of the awards in SDL's Tridion MVP (Most valued professional) programme.
I'm on the list. I'm now a Tridion MVP. [insert happy-dance here]
I'd like to say I'm surprised and honoured, but as I was on the committee responsible for making the awards, I'll have to settle for simply being honoured. (Of course, I wasn't allowed to vote for myself.) The award is given to those people who have been most visibly involved in community activities in the world of Tridon. This mostly means being willing to share ones knowledge and experience with others, for example on the Tridion technical forum, ideas site or building blocks exchange. Notwithstanding the fact that participating in these activities is a pleasure in itself, I am very pleased to receive the award, and to be counted in the same company as the other MVPs.
I really hope that now as a group we can go on to do even more, and that the whole will prove to be greater than the sum of the parts.
So to my fellow committee members, and to the Tridion community at large; thank you.
XML Namespaces aren't mandatory, and tools shouldn't assume that they are.
In his recent blog posting on XML Namespaces, James Clark questions the universal goodness of namespaces. Of course, there is plenty of goodness there, but he's right to question it. He says the following:
For XML, what is done is done. As far as I can tell, there is zero interest amongst major vendors in cleaning up or simplifying XML. I have only two small suggestions, one for XML language designers and one for XML tool vendors:
-
For XML language designers, think whether it is really necessary to use XML Namespaces. Don’t just mindlessly stick everything in a namespace because everybody else does. Using namespaces is not without cost. There is no inherent virtue in forcing users to stick xmlns=”…” on the document element.
-
For XML vendors, make sure your tool has good support for documents that don’t use namespaces. For example, don’t make the namespace URI be the only way to automatically find a schema for a document
It's the second point that interests me. During a recent Tridion project, there was a requirement to accept data from an external source as an XML document. I wanted to use a Tridion component to store this data, as this would give me the benefits of XML Schema validation, and controlled publishing. The document didn't have a namespace, although it had a schema. In order to get this to work with Tridion, I had to go to the provider of the document, and get them to add a namespace. Tridion wouldn't allow me to create a schema whose target namespace was empty. It seemed a shame that even when hand-editing the schema (so presumably asserting that I knew what I was about) the system wouldn't let me make this choice.
At the time, I just got the other party to make the change, and went back to more important things. Maybe there's some internal constraint in the way Tridion works that prevents them from supporting this, or maybe it's such an edge case that no-one was ever bothered by it. If the former, then I can't think what the problem would be; there's no reason to abuse the namespace to locate the schema. Tridion's quite happy enough to allow several schemas targetting the same namespace, so what's so special about the "no" namespace? In Tridion components, XML attributes (quite correctly) are in no namespace, but as long as the correct schema gets used for validation, so what?
I suspect it's more likely that this just comes under the "edge case" heading, in which case, perhaps they can improve it in a future release.
Dilbert finder
A long time ago, I worked in a job where the boss was "pointy-haired", and we habitually referred to some of the manifestations of his pointy-hairedness as "mauve". Why was this? Well it all came about as a reference to a specific Dilbert cartoon. Tioday I followed a link from Raymond Chen and ended up at the Dilbert strip finder. I typed in database (why not mauve?), and the second hit was the cartoon that explains it all. What's not to like?
Down for everyone, or just me?
I saw this mentioned in passing tonight in #gentoo. It's a simple enough idea, but it makes one particular task very easy. When you're stuck behind layers of networking devices, sometimes it's hard to know whether your site is working for people outside your firewalls etc.
XML Schema validation from Powershell - and how to keep your Tridion content delivery system neat and tidy
I don't know exactly when it was that Tridion started shipping the XML Schema files for the content delivery configuration files. For what it's worth, I only really became aware of it within the last few months. In that short time, schema validation has saved my ass at least twice when configuring a Tridion Content Delivery system. What's not to like? Never mind "What's not to like?" - I'll go further. Now that the guys over at Tridion have gone to the trouble of including these files as release assets - it is positively rude of you not to validate your config files.
Being a well-mannered kind of guy, I figured that I'd like to validate my configuration files not just once, but repeatedly. All the time, in fact. Whenever I make a change. The trouble is that the typical server where you find these things isn't loaded down with tools like XML Spy. The last time I validated a config file, it involved copying the offending article over to a file share, and then emailing it to myself on another machine. Not good. Not easy. Not very repeatable.
But enter our new hero, Windows 2008 Server - these days the deployment platform of choice if you want to run Tridion Content Delivery on a Windows box. And fully loaded for bear. At least the kind of bears you can hunt using powershell. Now that I can just reach out with powershell and grab useful bits of the .NET framework, I don't have any excuse any more, or anywhere to hide, so this afternoon, I set to work hacking up something to validate my configuration files. Well - of course, it could be any XML file. Maybe other people will find it useful too.
So to start with - I thought - just do the simplest thing. I needed to associate the xml files with their relevant schemas, and of course, I could have simply done that in the script, but then what if people move things around etc., so I decided that I would put the schemas in a directory on the server, and use XMLSchema-instance attributes to identify which schema belongs with each file.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd"
OK - so I'd have to edit each of the half-dozen or so configuration files, but that's a one-off job, so not much trouble. The .NET framework's XmlReader can detect this, and use it to locate the correct schema. (although if it isn't correctly specified, you won't see any validation errors even if the file is incorrect. I'll hope to fix that in a later version of my script.)
I created a function in powershell, like this:
# So far this silently fails to catch any problems if the schema locations aren't set up properly
# needs more work I suppose. Until then it can still deliver value if set up correctly
function ValidateXmlFile {
param ([string]$xmlFile = $(read-host "Please specify the path to the Xml file"))
"==============================================================="
"Validating $xmlFile using the schemas locations specified in it"
"==============================================================="
$settings = new-object System.Xml.XmlReaderSettings
$settings.ValidationType = [System.Xml.ValidationType]::Schema
$settings.ValidationFlags = $settings.ValidationFlags `
-bor [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation
$handler = [System.Xml.Schema.ValidationEventHandler] {
$args = $_ # entering new block so copy $_
switch ($args.Severity) {
Error {
# Exception is an XmlSchemaException
Write-Host "ERROR: line $($args.Exception.LineNumber)" -nonewline
Write-Host " position $($args.Exception.LinePosition)"
Write-Host $args.Message
break
}
Warning {
# So far, everything that has caused the handler to fire, has caused an Error...
Write-Host "Warning:: Check that the schema location references are joined up properly."
break
}
}
}
$settings.add_ValidationEventHandler($handler)
$reader = [System.Xml.XmlReader]::Create($xmlfile, $settings)
while($reader.Read()){}
$reader.Close()
}
With this function in place, all I have to do is have a list of lines like the following:
ValidateXmlFile "C:\Program Files\Tridion\config\cd_instances_conf.xml" ValidateXmlFile "C:\Program Files\Tridion\config\live\cd_broker_conf.xml"
If I've made typos or whatever, I'll pretty soon find them, and this can easily save hours. My favourite mistake is typing the attributes in lower case. Typically in these config files, attributes begin with a capital letter. Once you've made a mistake like that, trust me, no amount of staring at the code will make it obvious. You can stare straight at it and not see it.
So there you have it - as always - comments or improvements are always welcome, particularly if anyone knows how to get the warnings to show up!
SDL Tridion's YouTube marketing
In recent times, SDL Tridion have been putting out marketing videos on their very own YouTube channel. Each one takes a fictitious (or perhaps anonymised) use-case for their products and presents a fairly non-technical view of it by means of animated graphics, with voice-overs in disconcertingly generic varieties of British English. Never mind British, it's English English, of a sort of carefully not-too-posh-but-not-too-common-either, home-counties kind.
It's a bit strange for me. Obviously, I'm not the target audience. The videos are aimed at non-technical people who are not familiar with Tridion. Over the years I've got to know Tridion pretty well, both as a company and as a product suite. From so close up, the videos have an almost surreal aura. The multitudinous mismatches between the marketeers' in-world reality, and my own, leap out at me.
Why British English, when it's a Dutch company, whose biggest growth market is the US? Why this particularly strange variant of British English? (OK - full disclosure here; I'm a Geordie!) Is this the SDL influence, or does this come from US marketeers?
And are the examples real? I'm curious.
And so on....
As for the content, at least the most recent one (SDL Tridion WCM Platform for Syncronizing Online Content) had me jumping up and down in a couple of places. Like this: "... I can always revert back to previous versions of any content. It is important for our compliance department that we have proof of how a web site looked at any date in the past". Talk about a confusing message. Firstly, normal versioning in Tridion is not intended for that, and won't meet that need. They have a separate product called Archive Manager, which could be used to implement a solution for this problem.
Of course, if their marketing department were to put out a message aimed at someone like me, they would almost certainly deserve to be fired on the spot. It just hits my weirdness button. Know what I mean?
Be afraid.... be very afraid!
Over the last few years I've vaguely tracked a couple of hacking blogs; mostly to keep myself scared. The thing is - the bad guys are very, very creative and highly technical. They figure out ways to piece together lots of small, apparently insignificant, quirks in the way the Internet works, and use it to get access to things they shouldn't. It's good to remind yourself of this regularly if you work in the web business, because it's very important to secure the small, apparently insignificant stuff.
One of these blogs is that of RSnake, who apparently is a white-hat hacker. I say apparently, because how would you know if he was a black-hat? (Or is the proper term in this case grey-hat?) Assuming he is as white as the driven snow, I'm sure he wouldn't mind me suggesting that you visit his site (perhaps via the link in the next paragraph) at your own risk. You should be scared to visit the site of someone with these capabilities. As for who else has them, well again, how would you know?
He's just released a video explaining DNS Rebinding. What's that? Well if you don't already know how HTTP, DNS, TCP/IP work and a fair bit about web browsers and servers, you are excused at this point. By all means watch the video - it gets a bit technical, but along the way he's explaining how a bad guy can reach inside your intranet, past all your firewalls and security, and steal information from your internal servers. Just by getting you to click on a link.
The nice thing about seeing a video is that it makes it all a bit more concrete, and a bit more real. If you have any colleagues who don't seem to care too much about doing all the detailed work on securing a server, show them this. It might wake them up.
Web site spring clean... well winter clean anyway
Someone recently pointed out to me that this web site is terminally ugly, and doesn't do much credit to someone who is a web content management specialist, and who builds other people's web sites for them. Busted, eh?!
Yes, well of course, they were right. It's purely a matter of time and attention, and finally the notion of giving the web site some love has reached the top of the stack. I've upgraded the server to Plone 3.3.1, and I now have a separate instance running on my laptop, allowing for some sort of controlled development process. I've started this evening with a couple of minor edits to fix some of the more obvious irritations with the site styling. Truth be told, it needs much more than a bit of minor fixing, and if I can plan some time for it, I'll probably have to re-do the entire look and feel. I dare say I need some graphical help, but in general I think I'll go back to my old plan, which was having a site with very boring styling. If you're going to slap huge swathes of royal blue and spruce green across your site, you'd better know what you're about, and frankly I don't. I am a graphics noob, a design boob and an aesthetic anomaly.
Watch this space.
9 troubleshooting questions
Some questions from Tess Fernandez to help when troubleshooting complex problems.
The wrong level of abstraction, YAGNI, LOLA, and the fallacy of re-use.
Almost as an aside, in his recent post "And get rid of those pesky programmers", Phil Haack spins out a link to Udi Dahan's "The fallacy of ReUse". Coupled with the fact that I'd just read Jeff Atwood's "The Wrong Level of Abstraction" and that this subject is a hobby horse of mine, well I have to write something, eh?
It's all about judgement, isn't it? I mean - the kind of judgement that you expect people to acquire as they gain experience in software development. When do you re-use something, and when do you just re-do the job. As a web content management (WCM) specialist, my own work often involves creating templates that generate web pages based on content entered into other parts of the system by authors and editors. My weapon of choice in this endeavour is Tridion. As with other WCM tools, the templating facilities provide you with the ability to write out the HTML of the page design, and inject specific items of data where you want. In my (not so?) humble opinion, this is exactly the right level of abstraction for dealing with the specified problem, viz. that of creating a web page.
Some people, given the same task and tools, will immediately factor every single thing into a reusable library of functions. I don't do this, and sometimes a new colleague will be surprised at this, or even say they think it's wrong. My first response is usually to tell them that as and when there is a second occasion when I need the same functionality, I will either factor it out to something more abstract, or maybe just wait for the third occasion. As the agilists will have it, You ain't gonna need it (YAGNI). The problem goes further, however. Often I am faced with a choice between writing a few lines of code locally, very closely focussed on the specific output I need, or using/creating some generic function that will give me the output I need, if only I can figure out exactly how to invoke it. Maybe it will almost do what I need. <blink>No problem, I can always tweak it up a bit and add a parameter or two. Right?</blink>
I recently came across a function whose purpose was to create hyperlinks. It would accept about ten parameters, and could produce perhaps 20 variations on the theme of a hyperlink. In order to use this function, you have to open it up and read it, otherwise you don't know how its going to behave. (I'd defy anyone to thoroughly document the consequences of combining the parameters in different ways.) So a clear and present danger in creating an abstraction is that you create a leaky abstraction. (With more than a nod in the direction of Joel Spolsky's splendid article on the Law of Leaky Abstractions, or LOLA to her friends!)
So wrapping up this trivial stuff into an abstraction just made it non-trivial to work with. Result! Actually - all the function really did was dispatch to (hopefully) the correct code snippet based on the parameters. Having the code snippets locally in the templates would have been much easier to read and less error prone. The API provided by the vendor was already at the right level of abstraction, and further abstracting it was probably a mistake.
Of course, it's not as simple as that - otherwise we would never have started down this road in the first place. There is benefit in creating library functions, but mostly it's not about saving you from writing the same three lines of code in a bunch of places. It's often the case that what you want is for any change in the behaviour of your function to be propagated automatically to all the places it's called from. The only trouble is, you can't tell after the fact whether all the people you called your code knew that this was your intention. Udi Dahan notes that the characteristic property of code which you want to reuse is that it is generic. He also notes that re-use introduces dependencies, and that dependencies are what cause all the pain and grief of software maintenance.
Jeff Atwood's problem was the other way round. His choice had been to programme at a lower level of abstraction, when perhaps choosing to use a higher level library written by domain experts would have saved him from mistakes caused by him not understanding the low-level implementation details well enough.
So when you think about moving some code into a library, think about why you're doing it. If your purpose is to capture expertise that your client programmers don't have, you are probably doing a good thing. In this case, your library will probably have a very clear, tightly focussed purpose. There must be no possible ambiguity (or leaks, if you prefer) in the API you expose. When I invoke YAGNI against prematurely factoring code out into libraries, I can hope that this introduces a shakedown period between on the one hand, needing some code, and on the other hand, needing to introduce a layer of abstraction. Without this shakedown period, it's quite unlikely that my decision to abstract will be conscious enough to encompass those questions:
- Will my library be generic?
- Is it a genuine (watertight?) abstraction, in that a naive programmer can simply call it with the assurance that the domain experts have done their job within?
- Am I happy that whatever updates and bugfixes the library gets will be appropriate for all its clients?
- Will I have problems updating the library because I don't dare break its clients?
Of course, the "domain expert" might be the programmer who writes the client. Even so, getting the interface right is just as important for your own peace of mind. Then you can afford to forget some of the detail of the inner workings.
Coming back to re-use: we are often faced with managers who assume that re-use is always good. It is up to us as technicians to make the right judgements about what should be re-used, and then if necessary inform and explain. As Udi implies, building for re-use is often synonymous with lock-in to maintenance hell. Sometimes, the right decision is to build disposable code on top of cleanly factored abstractions. The HTML templating I began with is a good example. If the site design changes, it probably makes sense just to throw the old templates away and start again. Because the underlying API gives me clean access to the various fields in the content, I can put together another page template very quickly - probably quicker than figuring out all the dependencies under the old design. Jeff's example of JQuery is another good one. Because the library is so powerful and tightly engineered, it's not going to take you long to simply re-implement your desired behaviour when the design changes.
Re-use is unlikely to be successful unless the code being re-used was explicitly designed with that in mind. Simply factoring some code out to keep it tidy isn't the same thing as building a library. Be careful that you don't accidentally give the impression that your code is intended, designed and implemented for re-use if it isn't. It's OK to write disposable code too, especially if you know the difference between the two.
Server upgrades - portage hell and beyond
Oh what fun you can have once you start to upgrade a previously working server.
Amsterdam
Ingrid's "Where I live" post highlights some of the bizarre perceptions people have of Amsterdam and why a person might choose to live there. When I first came here, I was struck by the number of my countryfolk whose immediate thought was "you'll be stoned all the time then".
For sure, the regulations concerning cannabis are relatively liberal here. For me that mostly means that I know that there may possibly be some in the house, but I have no idea where it might be. Maybe it was the victim of a spring-cleaning frenzy. In less liberal regimes, you damn well know where your stash is at.
Nice one Jeff. How to make copy-paste coding a useful practice
Jeff Atwood has come up with a very nice suggestion. http://www.codinghorror.com/blog/archives/001257.html
OK - Fizzbin was funnier, but this might actually work.
Powershell profile for Tridion development
My powershell profile for Tridion and general .Net development

