Hello world!

There are stories to tell of the last week, but they'll have to wait for another day. However, I'm happy to say that my blog is again active, though none of the old content is there yet. Running it on WordPress now, on a shared host, which is quite a different experience. Hopefully have it all rebranded and all the old content imported by the weekend, but we'll see.

Glad to be back either way, though I've discovered a bit of a dislike for PHP. It's like the took the worst parts of Perl and C, tacked on some custom tweaks (like a global function namespace) and made a langauge out of them. Ick. I'm sure part of it is just the way WordPress is architected, but even so.

Weird DST Issue

Question: When is 7 days ago not 168 hours ago?

Answer: When DST changes during the 7 days, in which case it's either 167 (in the spring) or 169 (in the fall) hours ago.

I've got some graphs that display the current day and a seven days in the past, but the x axis is actually built based on hours (e.g. today's midnight is hour zero, yesterday's noon is hour -12, etc).  I'd done the queries to just extract data from seven days before midnight on, and wondered why my graphs were all screwy this week.  After quite a search, I realized that I was getting seven days, but seven days didn't equal 168 hours, and that the DST change was the reason.

In this specific case, the assumption was actually that every day was exactly 24 hours long, and while that holds true the majority of the time, it's an incorrect statement two days per year.  So watch out.

I'm not really sure what the general solution is if you need to assume a day is of a certain length.  In my case, I just changed the queries to be hour based, so seven days before midnight today is actually being extracted as one AM on 10/24.  Not ideal, obviously, but in my case having exactly 168 hours was more important than 168 hours ago being a midnight.  I suppose the right solution would to have sunday's section of the graph be 1/24th larger than the other days to accoun for the extra hour, and actually display 169 hours.  But the charting engine won't handle that.

Google Notebook

For those of you not aware, Google Notebook is a little online notebook for keeping track of "stuff" while you're online.  What's kind of neat about it, however, is the way that you use it.  In addition to the main interface, you can get a browser plugin that will open a mini-interface on whatever page you're currently viewing and allow you to do the core tasks.  It'll also automatically reference the page your on as part of you note, which makes for a handly little way to do "super bookmarks".

Like everything else Google, it's attached to your Google account, so you can access it from any computer that you're signed into Google on.  That includes the plugin, which is a nice touch.  A lot of plugins I've seen require you to configure the account they'll access as part of the plugin config, rather than using a standard cookie-based HTTP session.

As one last little tidbit, you can make one or more of your notebooks (you can have an arbitrary number) public if you so desire, so anyone can view them.

Granted, it's not a mind blowing app, but it is something that's useful.  As is their style, they've boiled the application down to it's essence, and implemented just that core in a well thought out and easy to use manner.

Subclipse vs. Subversive

To my knowledge, there are two free Eclipse plugins to use Subversion as a team provider: Subclipse and Subversive. I started out with Subclipse, but after Eclipse started crashing a lot when I moved from coding to team tasks, I pulled down Subversive to give it a whirl, hoping it would address the crashes. Which one did I just finish uninstalling, you ask? Read on.

First off, using Subversive didn't resolve the crashing, so it's either the team framework code, or something else (I've a suspicion debug-mode Tomcat instance I've always got running).

By and large, the two plugins were very similar. Minor differences included slightly different ordering of options on the context menu and different icons/labels. A large percentage of the UI, however, is driven by the core team framework, not the individual plugins.

Some of the more significant differences included the ability to create working copy change sets with Subversive, but not Subclipse. That can be quite handy if you're stuck working on two (or more) different things in the same working copy at the same time. Subversive also had a bit more intelligent repository browsing, automatically detecting the "standard by convention" trunk/tags/branches top-level directories and letting you browse them for what they are, rather than just generic directories. For a lot of operations, Subversive seemed noticably faster, but on occasion it would take forever to do the simplest things (like commit a single small file). Finally, Subversive's various dialogs exposed a rather richer feature set, though the vast majority of it is useless to me.

Subclipse, on the other hand, had very consistent performance. It also was much faster to "spin up" when loading a project for the first time and building all it's internal metadata for label decorations and stuff. It also seemed slightly faster on synchronize operations. One rather significant advantage for Subclipse was the merge viewer. While it's not for the faint of heart, it's quite powerful, and on the couple merges I did with Subversive, I felt slighted. One little edge case that I did find, Subclipse will let you connect over SSL to a repository whose SSL cert requires manual confirmation to accept (expired, non-trusted issuer, etc.), while Subversive just said it couldn't connect to the repository without attempting to get that confirmation. Not a huge deal, but I run my repos on a self-signed SSL cert, so I couldn't connect to them with Subversive unless something else (like Subclipse) had already done the confirmation.

So which one did I keep? Subclipse. Subversive's definitely got the potential to scoot by Subclipse in terms of feature set and usability (and will get a big boost if it becomes and official Eclipse project), but at the moment, Subclipse isn't lacking a bit. To be fair, Subversive has targetted a larger feature set and is a younger product, but I'm not considering developer merit, only how well it fits my needs. I know I'll be revisiting this question again next year sometime, and I'm not confident predicting either way.

Software Licensing

My last post about my transaction management advice for ColdSpring spawned a little debate about licensing between Sean and I, and I'm curious for feedback from the community at large.

The crux of the debate is that I released the component under the GPL, which is very restrictive license that nearly disallows use in commercial products.  Certainly not a good way to get wide adoption in a commercial setting.

With the license, however, was an offer of a commercial-friendly license (ASL, MIT, etc.) for the cost of an email describing the intended use.  I don't think that's a steep price to pay, even for something as trivial the advice component.

Reasonable?  Unreasonable?  Alternate tactics for the same end result?   I'm all ears…

Transaction Advice

As I've alluded to a couple times, I've put together a transaction advice implmentation for ColdSpring that uses the built-in AOP framework to transactionalize your service method invocations.  No more CFTRANSACTION tags in your code, and no more having to jump through hoops to avoid nested transactions with delegating calls in your service layer.  Just slap the transaction aspect into your app, set it up via a ProxyFactoryBean on the relevant ColdSpring beans, and away you go.  Further documentation and examples are available in the component itself.

I've opted for the GPL on this project, but if you have need of a different license, just let me know, and that can be arranged.  I'm not out to make money, just forcing people to ask for a commercial-friendly license will let me get a feel for how it's being used.  Let me say that again: commercial licenses will not require monetary compensation, just an email with some info about how you're using it.

Another ColdSpring Gotcha

Found another gotcha with ColdSpring yesterday.  Chris confirmed it as a bug on the mailing list, but thought I'd share here as well.  If you have a circular dependancy between two proxied beans, the dependancy is only "half" resolved.  That is, one bean will get a correctly proxied object injected, but the other will get an uninitialized ProxyFactoryBean instance.  Here's an example:

<bean id="imageservice" class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<bean id="imageserviceTarget" class="sorter.cfcs.imageservice">
<property name="recipientservice"><ref bean="recipientservice" /></property>
</bean>
</property>
<property name="interceptorNames">
<list>
<value>transactionAdvice</value>
</list>
</property>
</bean>

<bean id="recipientservice" class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<bean id="recipientserviceTarget" class="sorter.cfcs.recipientservice">
<property name="imageservice"><ref bean="imageservice" /></property>
</bean>
</property>
<property name="interceptorNames">
<list>
<value>transactionAdvice</value>
</list>
</property>
</bean>

What's the solution?  You have to avoid the circular dependancy through the proxies.  You could have half the dependancy reference the non-proxied (target) bean directly, but then you lose whatever aspects the proxy is applying.  The better solution is to make both beans BeanFactoryAware (by adding a setBeanFactory method that accepts an object of type coldspring.beans.BeanFactory), and then define and configure an init-method for both objects and manually get the dependancies from the bean factory in the configure method.  Not an ideal solution, obviously, but it does allow you to use the applied aspects.

A Couple ColdSpring AOP Gotchas

I've been playing with ColdSpring a little on one of my personal projects, and ran into a couple gotchas that I thought I'd share.

First, if you use dynamic default values on method arguments (e.g. <cfargument name="createDate" default="#now()#" />), when ColdSpring proxies that method, the default will be converted to "[runtime expression]".  This isn't ColdSpring's fault, but rather a limitation of the getMetaData() function.  The same behaviour is visible in the CFCExplorer (which is another good reason to use CFCDoc).  As such, the only solution is to actually remove the dynamic defaults, probably just to recreate them with a structKeyExists() call inside the method body to reset the value.

Second, if you have methods with package access in your CFCs, ColdSpring will proxy them and retain the access level.  However, the proxied objects are all in package coldspring.aop.framework.tmp, which means if you have any non-proxied objects invoking those methods, CF will balk as they're no longer in the right package.  I'm not sure if ColdSpring should always create proxied methods with public access (thereby removing the runtime restrictions, but still allowing your code – particularly for generating documentation from – to indicate the "correct" access).  Regardless, as things stand today, you must change the access to public if you want the proxied method to be called from non-proxied CFCs.  There is also a "weird" scenario the other way.  Since all proxied CFCs end up in the same package, all proxied CFCs can call package methods on all other proxied CFCs, regardless of the package that the original CFCs existed in.

Aside from these two issues, I've got a transaction managment aspect running flawlessly, which means no more issues with nested transactions, and no more CFTRANSACTION tags.  I've got a little more testing to do, but I'll be releasing that here in the near future.

Flash/Flex for Linux: it's BS!

Based on al the hubbub around Adobe making Flash/Flex stuff available for Linux, I have to comment that none of it is available for Linux.  It's available for Linux/i386, which is a totally different beast (Linux running on the i386 architecture).  It excludes Linux running on any other architecture (such as PPC or SPARC).

So please, Adobe, get your  language straight.  Or better yet, make it actually available for Linux.

Duck Typing

To this point, I've avoided much participation in the 'duck typing' discussions that seem to have pervaded the CF community for the past months.  But I saw this point on Dooce (which is a non-technical blog that just happened to be accidentally relevant) about it, and had to provide some commentary.

The narrative, while totally divorced from the world of software development, illustrates an interesting facet: what if it's "kind of" a duck?  Obviously Jon (the father) is not Heather (the mother – who is not my wife Heather either).  But does he pass the test in this one scenario?  Yes.  Is he duck enough?  No.

You might be tempted to say "yeah, he's duck enough", based on the narrow confines of this discussion, but I encourage you to not fall into the trap.  If he's duck enough in one scenario, but not duck enough in a different scenario, there's some major inconsistencies.

Back to programming, say you have an object parameter to some method that does a few different things (via delegation, of course) that don't involve a database (so they're not protected by a DB transaction).  The method uses it's argument to initiate the first process without issue.  Same for the second.  But the third errors, because the object isn't duck enough to help with the third process, even though it worked for the first two.

What can you do?  You can enforce formal typechecks where possible (on the CFARGUMENT tag in this case), but other than that, you just have to pray.  But we all know prayer isn't a good tactic for building robust enterprise applications, so we have to very carefully monitor all the places that call the method and ensure they don't pass something that's "kind of" a duck, but that's a PITA.  Or we have to build in a bunch of extra "duck enough" validation at the top of the method to ensure all three parts will succeed, but that leads to greatly increased coupling.  Or we could use some structured exception handling to catch any errors and manually undo the stuff that's already been done (a la a transaction), but hard to accomplish with sending emails or something.

I'm not against duck typing or dynamically typed languages, though I do prefer the statically typed ones in general.  Dynamic typing can grant you flexibility that can massively speed development, but it can also introduce weird loopholes in logic that are very difficult to deal with, because of this "duck enough / not duck enough" scenario.