Thursday, May 19, 2011

Proton Changes

It turns out the old mechanism for injecting prototypes in proton collided with Spring's AOP infrastructure to produce some truly nasty results. Trying to do field injection on cglib-generated proxies turns out to be... truly impossible. Like, really impossible. The Lord Himself couldn't do it.

So.

Going back to the drawing board I tried to figure out another solution to my prototype-injection problem. After googling around a bit I came across this very interesting blog entry about using Spring lookup-methods to generate prototypes. Very interesting.

After thinking about it a little bit I was a bit put off by the use of abstract methods in this case. This seemed to be very intrusive to me; it would make such classes difficult to test and it would change the fundamental "meaning" of a class (abstract classes are meant to be subclassed) just to fulfill this one "implementation detail" requirement. It also occurred to me that this behavior was virtually a perfect use-case for AOP. So after playing around a bit I came upon something like:

@PrototypeGenerator
public Foo createFoo(String constructorParam) {
return new Foo(constructorParam);
}

The idea here was you simply create and implement such 'prototype factory' methods and tag them with a @PrototypeGenerator annotation. At runtime, in Spring, such method calls would be intercepted by a PrototypeGeneratorAdvice that would go to the Spring ApplicationContext and create these beans and also do constructor-arg injection.

Of course this fails miserably because when a (cglib-enhanced) methods calls methods on itself (through the this variable) these methods are not intercepted by the various AOP mechanisms without full-on bytecode weaving. Ugh. The way around this is to implement a XFactory class, a normal Spring bean that can be injected and annotated with the PrototypeGenerator annotations to your heart's content. Inject this into those beans that need to create prototypes and voila! you are good to go!

From a design perspective this is not so bad. The simple truth is that when a bean needs to construct a prototype this is an admission of a lack-of-knowledge (the best kind) ie the bean is saying 'I need to create an instance of Foo that has a well-known state but I don't have enough information to do so! I need a prototype I can just clone/new!'. So injecting a factory in this case makes sense and also ends up being very unobtrusive thanks to the magic of Spring AOP!

Monday, May 9, 2011

Dead PowerSkin

After shelling out $50 for a PowerSkin I was pretty bummed to see the device last little more than two months. Turns out that the microUSB port you you use to charge the skin is connected in a very flimsy, unreliable manner. It soon became loose after which charging the skin was a big pain (it had to be plugged in just right) until the port just came off. Ugh.

In retrospect PowerSkin is probably not the right idea. I'll probably get a simpler, smaller case and something like a portable solar-rechargable charger. This can be used to charge many devices, like the Nook, in addition to the phone, and, in theory, you're not left constantly hunting for an outlet!

MouseFeed

MouseFeed is a pretty awesome Eclipse plugin that encourages you to learn Eclipse's many, many, many ... many keyboard shortcuts. By default, each time you select an item from a menu it'll pop-up a window reminding you of the keyboard shortcut for that action. But, if you're a bit of a masochist, you can set it to 'enforce' the keyboard action; in this mode selecting the action does nothing and you must use the keyboard shortcut. After many weeks of cursing and irritation you slowly begin to get the hang of it...

Thursday, May 5, 2011

Diplomat, Gardener, Ninja ... Engineer

So a diplomat, gardener, and an engineer walk into a bar...

No, this isn't a joke. It's simply that time again of the year when people trot out their favorite metaphors of what software developers do. So far we've got software gardens and software diplomats. More will be along shortly, I'm sure.

I do find it somewhat remarkable (and a bit disturbing) that in 2011 it's still not really clear what it is that software engineers do all day. Many blame this "unstable" state of affairs on the youth of the discipline and its rapidly changing nature. There's some truth to this but such an explanation isn't convincing. This confusion about the job -- what it is, the best way to do it, how to evaluate it, how to improve it -- comes from somewhere. There is something, some X factor, that makes it genuinely difficult to make firm assertions about the profession and which requires so many different analogies and metaphors to describe it.

What might this X factor be? Where does the confusion come from?

At this point we can trot out the usual suspects: 'complexity' or 'communication' or 'users' or 'C++' -- my favorite -- the general notion of 'change'. What's remarkable is that each of these villains that keep software engineers up at night are tremendously complicated subjects in their own right. There are whole disciplines devoted to studying and understand each of these fields. And yet they are only part of the problem of creating quality software -- there are other factors including technology, resource allocation, testing and verification, localization and more, more, more. You might as well say it's the world itself that makes software engineering hard. The world is confusing, unpredictable, ever-changing, and full of other human beings. It's obvious that such an environment would not be conducive to any serious engineering efforts. So who can blame us for being so confused when we're dealing with such inputs?

The point, I think, is that we could spend a lot of time identifying particular sources of confusion and elaborating particular strategies to deal with such confusion. Indeed this is a very valuable exercise. Yes, users are important but technology can only do so much and so we must employ diplomatic strategies to bridge the impasse. And yes, every software development project (like every family) is dysfunctional in its own special way and we must be attuned to these highly contextual and unique aspects of each project. But these are just two of many, many strategies that we could employ to deal with the vast (and ever increasing) quantity of confusion and uncertainty that exists in our projects. Software Engineering is confusing and hard because it's literally made up of many, many confusing and hard stuff. There is no single 'problem' or 'mystery' here, there is, rather, an ecosystem where problems, confusion and complexity are constantly growing and evolving. And we have to live in it and, hopefully, live somewhat comfortably.

There are people who are specially trained to bring order and predictability to this pit of chaos. The problems they work on are 'fractally complex'; the more you dig into them and try to break down the more you find yourself confronted with new and strange problems. There are never any clear solutions and so tradeoffs must be made including tradeoffs about the tradeoffs! Because there are no formulas, no well-defined procedures, that will solve such problems these people are forced to rely on a hodgepodge of different strategies and tools including, but not limited to, science, math, duct tape, ingenuity, magic, dialogue, modelling and plain old luck to 'handle' these problems and introduce some sort of stability to people's lives. It's not so much that they eliminate complexity and risk and they certainly don't always make things 'simpler' -- it's more that they understand it, accept it, study it, deal with it, and make it a little more easy to live with it.

These people are called engineers. The name is somewhat dated but calling them 'wranglers' sounds silly and calling them 'ninja' would make it very difficult for them to get through airports. The name sort of fits: engineer comes from ingenium -- Latin, for 'cleverness'.

And yes, I'd include software engineers among their number.

Never join already wrapped lines

Ever spend a bunch of time carefully formatting your code in Eclipse? Indenting everything just right? And then a few days later you lazily ask Eclipse to format your code and it smushes everything together, completely destroying your careful indentations?

Yeah, it sucks. Fortunately you can prevent it by enabling Java/CodeStyle/Formatter/Line Wrapping/Never join already wrapped lines. Once done Eclipse may even surprise you by indenting code you were too lazy to...

Wednesday, May 4, 2011

proton

I decided to go ahead and throw proton up on BitBucket. What is it?

Proton is an implementation of the common Prototype Design Pattern. What this boils down to is a single interface Prototype for creating copies of a pre-configured instance. An implementation can do whatever it wants to create prototypes, but once you pass the Prototype implementation off to clients it should do a good job of consistently returning usable copies from the newInstance method.

Why is this useful? Originally the Prototype pattern was used to implement a kind of object pooling because creating new objects is expensive. But the pattern is actually much more useful and powerful than this; the Prototype pattern can be used anytime one object needs to (continually) create instances of another object the creator either does not or should not have enough information to actually do the creation on its own. This tends to happen when objects have a 'structural' relationship rather than a functional relationship. A needs to create B and offer it on demand to C but A generally never invokes methods on B and doesn't know much about it at all.

In my particular case I was using JAXRS sub-resources and needed to have Root Resources create child Resources. I was also using Spring and wanted my child resources to get dependency injection and AOP and all that good stuff. To work around this I created a SpringPrototype that will go to the ApplicationContext and instantiate my sub-resources. (This only works of course if your scope="prototype" for your sub-resource prototypes.)

The next question was how to have the root resources get their hands on Prototypes for the sub-resources. I could've just done this using plain ol' spring xml as prototypes are just plain beans at the end of the day but I saw an opportunity to save some time by creating a custom BeanPostProcessor that would automagically inject prototypes into those resource classes that needed it after Spring has done all of its normal DI.

abort: requirement 'dotencode' not supported!

If you install the awesome HgEclipse and point it at the even awesomer BitBucket you may run into the nasty error in the title. This is because the version of Mercurial packaged in HgEclipse is out-of-date and is now no longer compatible with BitBucket.

Don't panic. The fix is easy: go to Team -> Mercurial in your preferences and change your Mercurial Executable to use the awesome TortoiseHg eg set it to C:\Program Files\TortoiseHg\hg.exe. Now you're good to go, just right click on the projects and refresh their status.